Avdi Grimm は、彼の著書Object On Railsにいくつかの優れた例を示しています。
こことここで、彼がコールバック オプションを選択しない理由と、対応する ActiveRecord メソッドをオーバーライドするだけでこれを取り除く方法を見つけることができます。
あなたの場合、次のような結果になります:
class Order < ActiveRecord::Base
def save(*)
normalize_card_number if paid_with_card?
super
end
private
def normalize_card_number
#do something and assign self.card_number = "XXX"
end
end
[コメント「これはまだコールバックです」の後の更新]
ドメインロジックのコールバックについて話しているとき、私はコールバックを理解ActiveRecord
しています.Mongoidリファラーからの引用が何か他のものだと思う場合は修正してください.どこかに「コールバック設計」が見つからなかった場合.
ActiveRecord
コールバックの大部分 (全体?) は、前の例で取り除くことができるシンタックス シュガーに過ぎないと思います。
まず、このコールバック メソッドがその背後にあるロジックを隠していることに同意します。 に慣れていない人はActiveRecord
、コードを理解するために学習する必要があります。上記のバージョンでは、簡単に理解してテストできます。
ActiveRecord
コールバックが「一般的な使用法」または「分離感」を生み出すと、どちらが最悪になる可能性があります。コールバック バージョンは最初は良さそうに見えるかもしれませんが、コールバックを追加するにつれて、コードを理解するのが難しくなります (どの順序で読み込まれるか、どのコードが実行フローを停止するかなど...)、それをテストします (ドメイン ロジックはActiveRecord
永続化ロジックと結合されています)。
以下の私の例を読むと、このコードに嫌悪感を覚えます。臭いです。TDD/BDD を行っていた場合、おそらくこのコードで終わることはないActiveRecord
と思いますcard_number=
。この例がコールバック オプションを直接選択せず、最初に設計について考えるのに十分であることを願っています。
MongoId からの引用について ドメイン ロジックにコールバックを使用するのではなく、バックグラウンド ジョブのキューに使用するようにアドバイスする理由が気になります。バックグラウンドジョブのキューイングはドメインロジックの一部である可能性があり、コールバック以外のもの(オブザーバーとしましょう)を使用して設計する方が良い場合があると思います。
最後に、オブジェクト指向プログラミング設計の観点から ActiveRecord が Rails でどのように使用/実装されるかについていくつかの批判があります。この回答にはそれに関する良い情報が含まれており、より簡単に見つけることができます。また、ActiveRecord に取って代わる (しかしどれだけ優れている) 可能性があり、彼の弱点がないdatamapperデザイン パターン/ ruby 実装プロジェクトを確認することもできます。