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

时间:2012-01-26 23:13:55

标签: ruby-on-rails ruby-on-rails-3 validation module

我试图将验证移到模块中。我想将现有对象扩展为一组无效的验证器,但我正在努力弄清楚如何让它们执行。有什么想法吗?

Active Record Object

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

1 个答案:

答案 0 :(得分:6)

我希望这可以提供帮助

6.1自定义验证器 自定义验证器是扩展ActiveModel :: Validator的类。这些类必须实现一个validate方法,该方法将记录作为参数并对其执行验证。使用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