How to call ActiveRecord validators as instance methods (ala Sequel)?

I have a model that needs different validators depending on the current state. How do I access ActiveRecord validators for a single instance? I would like to reuse as much plumbing as possible, but I'm not sure how to proceed.

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 should I duplicate all the built-in validator logic (i18n error messages, etc.)?

Is there an optional way to call Rails validators as instance methods? I think the Sequel instance-based authentication approach is more intelligent than the ActiveRecord class, but I'm not here to judge. I would like to return to solving more interesting problems. I just hope others come across this and can point me to some interesting stone or gem.

+3
source share
2 answers

I am sure that all validate_* methods can take a parameter :if , which can point to another method (and probably also take Proc), so you can expand your checks to be more than like:

 validates_presence_of :paid_at, :if => :paid? validates_association :purchaser, :if => :paid? 

To clear further, there is a with_options helper:

 with_options :if => :paid? do |v| v.validates_presence_of :paid_at v.validates_association :purchaser end 

Not sure if any of them can be used with the standard validate :custom_validate_method , though, but that won't surprise me.

+4
source

Is there a reason why this is inappropriate? It seems like it might work, but maybe metaprogramming has distorted my brain ...

 class Order < ActiveRecord::Base attr_accessible :state validate :state_specific_validations def state_specific_validations if :paid == self.state class << self validate_presence_of :paid_at validate_associated :purchaser end end end end 

The worst part is that the tests pass, so I'm not sure if I solved it or if I need the best tests. For example, I'm not 100% sure that this singleton modification does not affect other Orders.

sigh It takes a little sleep.

0
source

Source: https://habr.com/ru/post/1348106/


All Articles