2012-05-03 6 views
1

私のモデルでは、外部サービスにリクエストを送信するカスタム検証メソッドがあります。応答に基づいて、もしあれば、errorsアレイにエラーを追加します。検証からdbに書き込む必要があります

エラーがある場合は、エラーログを表すErrorLogモデルの新しいレコードを作成する必要があります。問題は、検証に失敗するとデータベース上でROLLBACKを実行し、新しいすべてのErrorLogレコードが失われることです。それを実装する最善の方法は何ですか?

after_rollbackは何らかの理由で呼び出されていないとも言えます。

答えて

3

after_rollbackは、トランザクション中に保存または破棄されたオブジェクトに対してのみ呼び出されます。メインクラスまたはErrorLogクラスにafter_rollbackコールバックを設定していますか?

実際にはafter_rollbackコールバックをErrorLogクラスに使用するのが最も簡単な方法です。もちろん

class MyClass < ActiveRecord::Base 
    before_save :check_external 

    def check_external 
    unless external_says_i_am_okay? 
     ErrorLog.create!(:message => 'oops') 
    end 
    end 
end 

class ErrorLog < ActiveRecord::Base 
    after_rollback :save_anyway 

    def save_anyway 
    self.save! 
    end 
end 

は、あなたが得ることのパフォーマンスを考慮したいと思うかもしれないすべての言った:あなたはErrorLogインスタンスを失うことになるだろう唯一の場合は、トランザクションがロールバックされている場合ので、このようなものが動作するはずですあなたのモデルを検証するための外部サービス。たとえば、Webリクエストの範囲内でオブジェクトを作成する場合、十分に速くない可能性があります。また、その時点までにトランザクションの範囲外になるため、ErrorLog#saveが失敗しないことを確認したいこともあります。

+0

ありがとうございます。私は自分の間違いを理解し、 'ErrorLog'モデルの中で' after_rollback'を設定します。しかし、「self.save!」は何もしません。ログにSQL(0.1ms)BEGIN \ nSQL(0.1ms)COMMIT'が挿入されていません。 – Flexoid

+0

トランザクション自体に「保存」されているため、すでに保存されていると思っているのだろうかと思います。その上に 'touch'を呼ぶか、属性を変更してセーブを人生に押し込むかどうかを調べることをお勧めします。コールバックが確実にそこにログインして呼び出されていることを確認する価値があります。 – Shadwell

+0

ErrorLog.create!(self.attributes)のみでエラーを保存できました。それは汚れたハックのように見えますが、私は他に何をすべきかわかりません。手伝ってくれてありがとう。 – Flexoid

関連する問題