2011-08-15 5 views
3

私は、現在の状態に応じて異なるバリデーターを必要とするモデルを持っています。インスタンスごとにActiveRecordバリデーターを呼び出すにはどうしたらよいですか?私はできるだけ多くの配管を再利用したいと思いますが、私はどのように続けるか分かりません。インスタンスメソッド(別名Sequel)としてActiveRecordバリデータを呼び出す方法は?

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 

私は、カスタムバリデータを使用することができますが、なぜ私はすべてのビルトインバリロジック(国際化エラーメッセージなど)を複製する必要があるでしょうか?

Railsバリデーターをインスタンスメソッドとして呼び出す方法はありますか? SequelのインスタンスベースのバリデータのアプローチはActiveRecordのクラスベースよりも妥当だと思いますが、私はここで判断するのではありません。私はもっ​​と興味深い問題を解決することに戻ってみたいです。私は、他の人がこれを見つけて、興味深い要点や宝石に向けることができることを願っています。

答えて

4

私はvalidate_*方法の全てが:ifオプション取ることができますかなり確信している - あなたのようなもっと何かであるためにあなたの検証を破ることができるように、別の方法を指す(そしておそらく同様PROCを受け入れる)ことができます。

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

は、さらに物事をクリーンアップするにはwith_optionsヘルパーがあります:どちらかがしかし、標準validate :custom_validate_methodで使用することができます

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

わからない場合 - それは私は驚かないだろう。

+0

ご意見ありがとうございます。 'with_options'は私が将来もっと多くのものを使っていることでしょう。私はあなたのソリューションを使用しているようですが、私が投稿した答えを最初に見ることはできますか?私はルビーシングルトンが私の脳を歪ませているかどうか分かりません。 :) – pithyless

0

これは不適切な理由はありますか?それがうまくいくかもしれないように思えるが、多分私の脳を反っメタプログラミング...

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%肯定的ではないが、このシングルトンの変更は他のオーダーに影響しない。

sigh睡眠が必要です。

+0

ここでの問題は、検証プロセス中にクラスレベル(受注ではなく、固有クラスのみ)で物事を追加することです。おそらくそれは動作しますが、非常に脆いと感じます。私はこのアプローチを全くお勧めしません。 – pat

関連する問題