У меня есть модель User, в которой есть адрес электронной почты и пароль. Для обеспечения безопасности они могут быть не равными друг другу. Как я могу определить это в моей модели?
Как проверить, что два значения не совпадают друг с другом в модели Rails?
Ответ 1
Создать пользовательскую валидацию:
validate :check_email_and_password
def check_email_and_password
errors.add(:password, "can't be the same as email") if email == password
end
Но имейте в виду, что сохранение пароля в виде простого текста - плохая идея. Вы должны хранить его хэшированным. Попробуйте использовать плагин аутентификации, например authlogic или Restful authentication.
Ответ 2
Чтобы проверить это, вы можете использовать специальный метод проверки.
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
Ответ 3
Это зависит от того, как хранится ваш пароль:
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
Это будет работать, если ваш пароль хранится буквально, но вы можете выполнить одно и то же с помощью электронной почты (например, создать хешированную версию) и проверить равенство с паролем. Например:
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
Мой пример взят из http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html#M002162
Ваша ситуация довольно общая, поэтому вам может быть интересно создать специальный метод проверки. Здесь все описано: http://guides.rubyonrails.org/active_record_validations_callbacks.html#creating-custom-validation-methods
Ответ 4
гораздо разумнее использовать настраиваемый валидатор, вот код универсального валидатора, который можно использовать
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
а затем используйте его как:
class User < ActiveRecord::Base
# ...
validates_with ValuesNotEqualValidator, fields: [:email, :password], msg: "This Person is evil"
end
Ответ 5
Новый способ:
validates :password, exclusion: { in: lambda{ |user| [user.email] } }
или
validates :password, exclusion: { in: ->(user) { [user.email] } }
Ответ 6
все, что вам нужно, это создать правило проверки в вашей модели например
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
Ответ 7
Если вы хотите поддерживать несколько языков, вам нужно придумать другое решение, которое переводит сообщения об ошибках и имена атрибутов. Поэтому я создал для них каждый валидатор.
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
Я называю это в модели следующим образом:
class User < ActiveRecord::Base
validates :forename, :surname, values_not_equal: true
end
И я перевешу это сообщение следующим образом:
de:
activerecord:
attributes:
user:
forename: 'Vorname'
surname: 'Nachname'
errors:
messages:
should_not_be_equal_to: 'darf nicht gleich sein wie'