自定义验证 - 适用于所有型号

时间:2015-10-08 01:20:52

标签: ruby-on-rails

说我有模特Foo,Bar和Baz。我想对每个表中的字段执行验证。因为它是相同的验证,我喜欢DRY代码,而且我很懒,我想在一个地方编写这个验证的逻辑,并且能够在模型中引用它,而不必写多于一个每个模型中的行 - 就像使用ApplicationController使多个控制器可用的方法一样。

实现看起来像这样:

class Foo < ActiveRecord::Base
  validates :some_field, :custom_shared_validation
end

class Bar < ActiveRecord::Base
  validates :some_other_field, :custom_shared_validation
end

但是我不确定这是否可行,或者,如果是这样,我在哪里写它。我知道extending ActiveRecord::Base is to write Concerns的一种方式,我在印象中允许你添加所有模型都可访问的方法,但我不确定这种做法是否扩展到在所有模型中使用这些方法作为验证器。

2 个答案:

答案 0 :(得分:2)

直截了当地表达关注......

module OmniVerifiable
  extend ActiveRecord::Concern

  included do
    validates :field, :custom_shared_validation
  end
end

...但是如果您正在验证的所有模型中的字段相同。

如果他们,那么你必须在两者中较差的一个之间做出选择:要么创建一个函数来带回你想要的自定义字段每个< / em>模型,或者你咬紧牙关并在每个模型中写下验证。

我的建议是单独写出验证,因为从概念上讲它们涉及不同的领域。如果他们是不同的领域,那么无论如何你都将重复工作 。不要让DRY太过于让你的代码变得简洁和不可读。

答案 1 :(得分:1)

请参阅http://guides.rubyonrails.org/active_record_validations.html#performing-custom-validations

回顾一下链接在某些时候发生变化的情况,在Rails 4中你会写一个继承ActiveModel :: Validator或ActiveModel :: EachValidator的类。该类需要分别实现validatevalidate_each方法。然后,您可以在任何模型或任何混合了ActiveModel :: Validations的类中使用它。