如何将ActiveRecordvalidation器作为实例方法调用(ala Sequel)?
我有一个模型需要不同的validation器,具体取决于它的当前状态。 我应该如何为每个实例调用ActiveRecordvalidation器? 我想重用尽可能多的管道,但我不知道如何继续。
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
我可以使用自定义validation器,但为什么我需要复制所有内置validation器逻辑(i18n错误消息等)?
有没有一种巧妙的方法来调用Railsvalidation器作为实例方法? 我认为Sequel基于实例的validation器的方法比ActiveRecord基于类的更合理,但我不是来判断。 我想回到解决更有趣的问题。 我只是希望其他人遇到过这个并且能指出一些有趣的要点或gem。
我非常确定所有validate_*
方法都可以采用:if
选项 – 它可以指向另一种方法(并且可能也接受Proc),因此您可以将您的validation分解为:
validates_presence_of :paid_at, :if => :paid? validates_association :purchaser, :if => :paid?
为了进一步清理,有with_options帮助器:
with_options :if => :paid? do |v| v.validates_presence_of :paid_at v.validates_association :purchaser end
不确定是否可以使用标准validate :custom_validate_method
– 但它不会让我感到惊讶。
这有什么不合适的原因吗? 它似乎可能有效,但也许元编程扭曲了我的大脑……
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
最糟糕的是测试正在通过,所以我不确定我是否解决了它或者我需要更好的测试。 例如,我不是100%肯定这个单例修改不会影响其他订单。
感叹需要一些睡眠。