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

14

我创建了一个有几个字段的模型,应该接受相同的数据格式(字符串,但可以是任何内容,FWIW)。我想将同样的验证规则应用到所有这些字段上。当然,我可以直接复制/粘贴内容,但那违反了DRY原则,也不符合常识...

我猜这很容易,但我是Rails新手/潮人,所以请原谅我一个琐碎的问题。=)

5个回答

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验证和回调指南;它提供了关于许多Active Record验证功能的全面见解。 您还可以在这里查看文档。


是的,但是对于像正则表达式匹配这样更奇特的东西呢? - aL3xa
没问题!我已经附上了一些详细信息/资源。如果您认为这个答案是解决方案,请通过点击我的帖子旁边的图标“接受”它。这将表示问题已关闭,您对我的帮助感到满意。祝你学习Rails顺利! - Jon McIntosh
谢谢Jon,我一直在问一些关于Rails的琐碎问题,但似乎在Google上找不到答案,因为它们太琐碎了,甚至连鸟儿都知道。但是...感谢您的回复,看来我需要更多地运用我的大脑!=)再次感谢! - aL3xa
2
这些绝对不是琐碎的问题;每个人都要学习这些东西,而且这些问题的类型会被问到。很多编程文档的问题在于它们是由那些对该主题有深入了解的人编写的,因此这些问题会被忽略。但是信息是可以找到的!你会比想象中更快地掌握Rails。 - Jon McIntosh
apidock 推荐使用以下代码验证电子邮件格式:validates :email, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, on: :create } - Archonic

5

如果您正在使用任何内置验证(如存在性、长度等),您可以像这样将单个验证应用于多个属性:

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/,该链接涉及关于Rails 3中的先进验证技术。

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

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

0

或者你可以使用 "with_options",例如:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接