How do I validate that two values do not equal each other in a Rails model?

前端 未结 9 1629
既然无缘
既然无缘 2020-12-29 20:31

I have a User model, which has an email and a password field. For security, these may not be equal to each other. How can I define this in my model?

相关标签:
9条回答
  • 2020-12-29 21:10

    Create custom validataion:

    validate :check_email_and_password
    
    def check_email_and_password
      errors.add(:password, "can't be the same as email") if email == password
    end
    

    But keep in mind that storing password as a plain text is bad idea. You should store it hashed. Try some authentication plugin like authlogic or Restful authentication.

    0 讨论(0)
  • 2020-12-29 21:12

    It depends how Your password is stored:

    class User < ActiveRecord::Base
        validate :email_and_password_validation
    
        def email_and_password_validation
            if self.email == self.password
                errors.add_to_base("Password must be different from email") 
            end
        end
    end
    

    This would work if Your password is stored literally, but You can perform the same thing with email (e.g. create a hashed version) and check for equality with password. E.g:

    class User < ActiveRecord::Base
        validate :email_and_password_validation
    
        def email_and_password_validation
            if make_hash(self.email) == self.hashed_password
                errors.add_to_base("Password must be different from email") 
            end
        end
    end
    

    My example is taken from http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html#M002162

    Your situation is quite general so You can be interested in creating custom validation method. Everything is covered here: http://guides.rubyonrails.org/active_record_validations_callbacks.html#creating-custom-validation-methods

    0 讨论(0)
  • 2020-12-29 21:12

    more fun:

      validates :password, exclusion: { in: ->(person) { [person.email] }, message: "cannot use protected password" }
    

    which might be even better in this case, since you could check for other forbidden values with something like

      validates :password, exclusion: { in: ->(person) { [person.email, person.first_name, person.last_name, person.phone_number, person.department_name] }, message: "cannot use protected password" }
    
    0 讨论(0)
  • 2020-12-29 21:13

    all you need is to create validation rule in your model for example

    class User < ActiveRecord::Base
      def validate_on_create
        if email == password
          errors.add("password", "email and password can't be the same")
        end
      end
    end
    
    0 讨论(0)
  • 2020-12-29 21:15

    You can use a custom validation method to check this.

    class User < ActiveRecord::Base
      # ...
    
      def validate
        if (self.email == self.password)
          errors.add(:password, "password cannot equal email")
          errors.add(:email, "email cannot equal password")
        end
      end
    end
    
    0 讨论(0)
  • 2020-12-29 21:21

    If you want to support multiple languages, you have to come up with another solution, which translates the error messages and the attribute names. So I created a new each validator for that.

    validators/values_not_equal_validator.rb:
    class ValuesNotEqualValidator < ActiveModel::EachValidator
      def validate(record)
        @past = Hash.new
        super
      end
    
      def validate_each(record, attribute, value)
        @past.each do |k, v|
          if v == value
            record.errors.add(attribute, I18n.t('errors.messages.should_not_be_equal_to') + " " + record.class.human_attribute_name(k))
          end
        end
        @past[attribute] = value
      end
    end
    

    I call it in the model like this:

    class User < ActiveRecord::Base
      validates :forename, :surname, values_not_equal: true
    end
    

    And I translate it the messages like this:

    de:
      activerecord:
        attributes:
          user:
            forename: 'Vorname'
            surname: 'Nachname'
      errors:
        messages:
          should_not_be_equal_to: 'darf nicht gleich sein wie'
    
    0 讨论(0)
提交回复
热议问题