如何在Rails模型中验证两个值是否彼此不相等?

时间:2021-01-04 11:25:04

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?

我有一个用户模型,它有一个电子邮件和一个密码字段。为安全起见,这些可能并不相同。我怎样才能在我的模型中定义它?

7 个解决方案

#1


25  

Create custom validataion:

创建自定义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.

但请记住,将密码存储为纯文本是个坏主意。你应该把它存储起来。尝试一些身份验证插件,如authlogic或Restful身份验证。

#2


6  

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

#3


5  

New way:

新方法:

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

or:

要么:

validates :password, exclusion: { in: ->(user) { [user.email] } }

#4


4  

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

我的例子来自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

您的情况非常普遍,因此您可能有兴趣创建自定义验证方法。这里涵盖了所有内容:http://guides.rubyonrails.org/active_record_validations_callbacks.html#creating-custom-validation-methods

#5


4  

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

#6


1  

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

#7


0  

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'

#1


25  

Create custom validataion:

创建自定义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.

但请记住,将密码存储为纯文本是个坏主意。你应该把它存储起来。尝试一些身份验证插件,如authlogic或Restful身份验证。

#2


6  

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

#3


5  

New way:

新方法:

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

or:

要么:

validates :password, exclusion: { in: ->(user) { [user.email] } }

#4


4  

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

我的例子来自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

您的情况非常普遍,因此您可能有兴趣创建自定义验证方法。这里涵盖了所有内容:http://guides.rubyonrails.org/active_record_validations_callbacks.html#creating-custom-validation-methods

#5


4  

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

#6


1  

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

#7


0  

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'