我创建了一个具有多个字段的模型,这些字段应该接受相同的数据格式(字符串,但可以是任何东西,FWIW)。我想将相同的验证规则应用于所有这些字段。当然,我可以继续复制/粘贴东西,但那也是反对DRY原则,也是常识......
我想这个很容易,但我是Rails的新人/潮人,所以 excuse-moi 这是一个微不足道的问题。 =)
答案 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