I have a model with many validations that can be grouped based on various conditions. The brute force way to handle it would be:
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
...
But that doesn't seem very DRY. Is there a good way to group the validations based on the conditions? The approach I came up with is:
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 Condit开发者_JAVA技巧ion2Validator < ActiveModel::Validator
...
end
validates_with Condition2Validator, :if => :condition2
Can anyone think of a better way?
Update: the way I posted above is flawed in that you cannot have if, unless, etc on the nested validators. Jesse's solution is much better.
This approach is from the multi-step wizard, where you only want to validate if you are on that wizard step. Should work for you as well
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
精彩评论