I've got a model that needs different validators depending on its current state. How should I go about calling ActiveRecord validators per instance? I'd like to reuse as much plumbing as possible, but I'm not sure how to continue.
class Order < ActiveRecord::Base
attr_accessible :state
validate :state_specific_validations
def state_specific_validations
if :paid == self.state
# Warning: here be Unicorns...
# Wishful thinking...
validate_presence_of :paid_at
validate_associated :purchaser
# Hopeful. What are the validators called internally in Rails?
errors << PresenceValidator.new(self, :paid_at).valid?
errors << AssociationValidator.new(self, :paid_at).valid?
# Plan B
# ... Hoping for help from the audience ...
else
# Even more complicated validator logic, hoping for some DRY validators
end
end
end
I could just use custom validators, but why would I need to duplicate all the built-in validator logic (i18n error messages, etc.)?
Is there a neat way of calling the Rails validators as instance methods? I think Sequel's approach of instance-based validators is more reasonable than ActiveRecord's class-based, but I'm not here to judge. I'd just like to get back to solving more interesting problems. I'm just hoping that others have come across this and can point me to some interesting gist or gem.
Is there any reason why this is inappropriate? It seems like it might work, but maybe metaprogramming warped my brain...
Worst part is that tests are passing, so I'm not sure if I solved it or I need better tests. For example, I'm not 100% positive this singleton modification does not affect other Orders.
sigh Need some sleep.
I'm pretty sure all of the
validate_*
methods can take an:if
option - which can point to another method (and likely accept a Proc as well), so you could break up your validations to be more something like:To clean things up further, there's the with_options helper:
Not sure if either can be used with a standard
validate :custom_validate_method
though - but it wouldn't surprise me.