通过扩展向ActiveRecord模块添加自定义验证?

问题描述:

我试图将我的验证移动到一个模块。我想将现有对象扩展为一组验证器,但我正在努力弄清楚如何让它们执行。有任何想法吗?通过扩展向ActiveRecord模块添加自定义验证?

的Active Record对象

class Test < ActiveRecord::Base 
    has_many :resources 
end 

验证

module TestValidator 
    extend ActiveSupport::Concern 

    included do 
    validates_associated :resources 
    end 
end 

控制台

t = Test.new 
t.extend TestValidator 
t.valid? 
# true ... should be false 

我希望这可以帮助

6.1自定义验证 自定义验证器是扩展ActiveModel :: Validator的类。这些类必须实现一个验证方法,该方法将记录作为参数并对其执行验证。自定义验证器使用validates_with方法进行调用。

class MyValidator < ActiveModel::Validator 
    def validate(record) 
    unless record.name.starts_with? 'X' 
     record.errors[:name] << 'Need a name starting with X please!' 
    end 
    end 
end 



class Person 
    include ActiveModel::Validations 
    validates_with MyValidator 
end 

添加自定义的验证器,用于验证各个属性的最简单方法是与加载ActiveModel方便:: EachValidator。在这种情况下,自定义验证器类必须实现一个validate_each方法,该方法接受三个参数:记录,与实例对应的属性和值,要验证的属性以及传递实例中属性的值。

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

class Person < ActiveRecord::Base 
    validates :email, :presence => true, :email => true 
end 

如示例中所示,您还可以将标准验证与您自己的自定义验证器结合使用。

http://guides.rubyonrails.org/active_record_validations_callbacks.html#performing-custom-validations

+0

嘿,本,谢谢你的帖子。这绝对是完成验证的理想方式。我试图得到一个模块/混入方法,但是,原因是我试图在DCI的意义上使用验证,有一个“TestValidator”角色。但考虑更多之后,我认为你上面提到的标准方法效果更好,因为在某种意义上,验证是数据。 – 2012-01-27 14:53:02