Rails 3:将相同的验证规则应用于多个表字段

时间:2012-03-20 20:46:03

标签: ruby-on-rails-3 validation rails-activerecord

我创建了一个具有多个字段的模型,这些字段应该接受相同的数据格式(字符串,但可以是任何东西,FWIW)。我想将相同的验证规则应用于所有这些字段。当然,我可以继续复制/粘贴东西,但那也是反对DRY原则,也是常识......

我想这个很容易,但我是Rails的新人/潮人,所以 excuse-moi 这是一个微不足道的问题。 =)

5 个答案:

答案 0 :(得分:21)

因此,如果你说三个字段要验证:

:first_name
:last_name
:age

你希望他们都得到验证吗?所以像这样:

validates_presence_of :first_name, :last_name, :age

编辑: Rails中有许多不同的验证方法,它们非常灵活)。对于字段的格式,您可以使用validates_format_of,然后使用正则表达式来匹配它。以下是匹配电子邮件的示例:

validates_format_of :email, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i

我会查看Active Record Validations and Callbacks指南;它提供了有关Active Record在验证方面提供的许多功能的全面见解。您还可以查看文档here

答案 1 :(得分:5)

如果您使用任何内置验证(presence,length_of),您可以对多个属性应用单个验证,如下所示:

validates_presence_of :name, :email

如果您有自定义逻辑,则可以创建验证器对象来存放代码并单独应用

class EmailValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    record.errors[attribute] << (options[:message] || "is not an email") unless
      value =~ /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
  end
end

def Person
  validates :home_email, :email => true
  validates :work_email, :email => true
end

请参阅:http://thelucid.com/2010/01/08/sexy-validation-in-edge-rails-rails-3/

答案 2 :(得分:3)

在Rails 4中,您可以使用循环对多个列应用相同的验证:

[:beds, :baths].each do |column|
  validates column, allow_blank: true, length: { maximum: 25 }
end

床和浴室均使用相同的验证进行验证。

编辑:

在Rails 4.2中,你可以通过在validates函数调用之后放置多个符号来做同样的事情。例如:

validates :beds, :baths, allow_blank: true

答案 3 :(得分:1)

使用Themis

# Describe common validation in module
module CommonValidation
  extend Themis::Validation

  validates_presence_of :foo
  validates_length_of :bar, :maximum => 255
end

class ModelA < ActiveRecord::Base
  # import validations
  include CommonValidation
end

class ModelB < ActiveRecord::Base
  # import validations
  include CommonValidation
end

答案 4 :(得分:0)

或者您可以使用“ with_options”,例如:

with_options presence: true do |video|
  REQUIRED_COLUMNS.map do |attr|
   video.validates attr
  end
end