Как мне проверить, что два значения не равны друг другу в модели Rails? - PullRequest
25 голосов
/ 16 февраля 2010

У меня есть модель User, в которой есть адрес электронной почты и поле пароля. В целях безопасности они не могут быть равны друг другу. Как я могу определить это в моей модели?

Ответы [ 8 ]

28 голосов
/ 16 февраля 2010

Создание пользовательской проверки :

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 аутентификация .

9 голосов
/ 17 мая 2017

Новый способ:

validates :password, exclusion: { in: lambda{ |user| [user.email] } }

или

validates :password, exclusion: { in: ->(user) { [user.email] } }
6 голосов
/ 16 февраля 2010

Вы можете использовать пользовательский метод проверки, чтобы проверить это.

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
4 голосов
/ 30 марта 2013

гораздо разумнее использовать пользовательский валидатор, вот код для универсального валидатора, который можно использовать

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
4 голосов
/ 16 февраля 2010

Зависит от того, как хранится Ваш пароль:

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

1 голос
/ 16 февраля 2010

все, что вам нужно, это создать правило проверки в вашей модели например

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 голосов
/ 17 октября 2018

Используя пользовательские проверки, мы можем выполнить эту операцию

validate: validate_address

def validate_address
errors.add (: permenent_address, "не может быть таким же, как present_address"), если self.present_address == self.permenent_address конец

0 голосов
/ 07 марта 2015

Если вы хотите поддерживать несколько языков, вам нужно найти другое решение, которое транслирует сообщения об ошибках и имена атрибутов. Поэтому я создал новый валидатор для каждого.

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'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...