Rails/ActiveModel将参数传递给EachValidator

GTD*_*Dev 12 validation aggregation activemodel mongoid ruby-on-rails-3

我有一个非常通用的验证器,我想传递它的参数.

这是一个示例模型:

class User
  include Mongoid::Document

  field :order_type
  has_many :orders, inverse_of :user
  validates: orders, generic: true #i want to pass argument (order_type)

  field :task_type
  has_many :tasks, inverse_of :user
  validates: tasks, generic: true #i want to pass argument (task_type)
end
Run Code Online (Sandbox Code Playgroud)

和示例验证器:

class GenericValidator < ActiveModel::EachValidator
  def validate_each(object, attribute, value)
    if some_validation?(object)
      object.errors[attribute] << (options[:message] || "is not formatted properly") 
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

有没有办法将参数传递给验证器,具体取决于验证哪个字段?

谢谢

小智 20

我也没有意识到这一点,但如果你想传递一个参数,那么就传递一个哈希来generic:代替true. 这篇文章详细介绍了您想要遵循的具体过程:

class User
  include Mongoid::Document

  field :order_type
  has_many :orders, inverse_of :user
  validates: orders, generic: { :order_type => order_type }

  field :task_type
  has_many :tasks, inverse_of :user
  validates: tasks, generic: { :task_type => task_type }
end
Run Code Online (Sandbox Code Playgroud)

GenericValidator现在应该可以访问您希望在验证中传递的两个参数:options[:order_type]options[:task_type].

然而,将它们分成两个验证器可能更有意义,两者都继承了dpassage提到的共享行为:

  class User
    include Mongoid::Document

    field :order_type
    has_many :orders, inverse_of :user
    validates: orders, order: { type: order_type }

    field :task_type
    has_many :tasks, inverse_of :user
    validates: tasks, task: { type: task_type }
  end
Run Code Online (Sandbox Code Playgroud)