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?
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 .
New way:
validates :password, exclusion: { in: lambda{ |user| [user.email] } }
or:
validates :password, exclusion: { in: ->(user) { [user.email] } }
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
it is much wiser to use custom validator, here is code for universal validator that can be used
class ValuesNotEqualValidator < ActiveModel::Validator
def validate(record)
if options[:fields].any? && options[:fields].size >= 2
field_values = options[:fields].collect { |f| record.send(f) }
unless field_values.size == field_values.uniq.size
record.errors[:base] <<
(options[:msg].blank? ? "fields: #{options[:fields].join(", ")} - should not be equal" :
options[:msg])
end
else
raise "#{self.class.name} require at least two fields as options [e.g. fields: [:giver_id, :receiver_id]"
end
end
end
and then use it like:
class User < ActiveRecord::Base
# ...
validates_with ValuesNotEqualValidator, fields: [:email, :password], msg: "This Person is evil"
end
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 (eg create a hashed version) and check for equality with password. Eg:
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
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" }
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
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'
By using custom validations we can do this operation
validate :validate_address
def validate_address
errors.add(:permenent_address, "can't be the same as present_address") if self.present_address== self.permenent_address end
Ruby on Rails 7.0 添加了validates_comparison_of
这样的validates_comparison_of
验证的支持
validates :password, comparison: { other_than: :email }
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.