如何组合多个Rails验证:if条件?

Bri*_*ing 5 validation ruby-on-rails

我有一个具有许多验证的模型,可以根据不同的条件进行分组.蛮力的处理方式是:

validates_presence_of :attr1, :if => :condition1
validates_something :attr2, :if => :condition1
validates_something_else :attr3, :if => :condition1
...

validates_presence_of :attr4, :if => :condition2
validates_something :attr5, :if => :condition2
validates_presence_of :attr6, :if => :condition2
...
Run Code Online (Sandbox Code Playgroud)

但这似乎不是很干.有没有一种很好的方法可以根据条件对验证进行分组?我想出的方法是:

class Condition1Validator < ActiveModel::Validator
  def validate(record)
    record.instance_eval do
      validates_presence_of :attr1
      validates_something, :attr2
      validates_something_else :attr3
    end
  end
end
validates_with Condition1Validator, :if => :condition1

class Condition2Validator < ActiveModel::Validator
...
end
validates_with Condition2Validator, :if => :condition2
Run Code Online (Sandbox Code Playgroud)

谁能想到更好的方法?

更新:我在上面发布的方式存在缺陷,因为你不能在嵌套验证器上使用if,除非等.杰西的解决方案要好得多.

Jes*_*ott 13

此方法来自多步骤向导,您只需要验证是否在该向导步骤中.应该也适合你

class YourModel 

  with_options :if => lambda { |o| o.whatever == "whatever" } do |on_condition|
    on_condition.validates_presence_of :address
    on_condition.validates_presence_of :city
  end

  with_options :if => lambda { |o| o.condition_the_second == "whatever" } do |on_condition|
    on_condition.validates_presence_of :foo
    on_condition.validates_presence_of :bar
  end
end
Run Code Online (Sandbox Code Playgroud)