我创建了一个有几个字段的模型,应该接受相同的数据格式(字符串,但可以是任何内容,FWIW)。我想将同样的验证规则应用到所有这些字段上。当然,我可以直接复制/粘贴内容,但那违反了DRY原则,也不符合常识...
我猜这很容易,但我是Rails新手/潮人,所以请原谅我一个琐碎的问题。=)
我创建了一个有几个字段的模型,应该接受相同的数据格式(字符串,但可以是任何内容,FWIW)。我想将同样的验证规则应用到所有这些字段上。当然,我可以直接复制/粘贴内容,但那违反了DRY原则,也不符合常识...
我猜这很容易,但我是Rails新手/潮人,所以请原谅我一个琐碎的问题。=)
所以,如果您需要验证三个字段:
: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验证和回调指南;它提供了关于许多Active Record验证功能的全面见解。 您还可以在这里查看文档。
如果您正在使用任何内置验证(如存在性、长度等),您可以像这样将单个验证应用于多个属性:
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
在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
# 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
或者你可以使用 "with_options",例如:
with_options presence: true do |video|
REQUIRED_COLUMNS.map do |attr|
video.validates attr
end
end
validates :email, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, on: :create }
- Archonic