を使用して、あなたが選択した一人ですので、私はActiveRecordのインポートを使用することはできません実際にアプリケーションをどのように構造化したいかによって異なります。私はあなたがカウンターのキャッシュの周りに得ることができるさまざまな方法について議論し、あなたがそうしたいと思っているかもしれないいくつかの考察を述べます。
基本的に、あなたはカウンターキャッシュの更新をスキップすることができ、3つの異なる方法があります。
- Monkey patch your model to disable the counter cache callback
- Use an update method that doesn't trigger callbacks
- はありません同じテーブルを指している代替モデルを定義します同じコールバック動作を使用し、データベースに一括挿入するときに使用します。
上記の最初の2つのオプションは、 ActiveRecordのコールバックを無効にすることに関連しています。これは、カウンタキャッシュがコールバックを使用して内部的に実装されるため意味があります。
Railsがカウンタキャッシュとの関連付けを持つモデルを読み込むと、コールバックメソッドが動的に定義されます。これらをコールバックとして無効にする場合は、最初にコールバック名が何であるか把握する必要があります。
これらのコールバックを実装するためにRailsが定義したメソッドを理解するには、主に2つの方法があります。 Railsソースを読み込んで、String intorpolationによって生成される名前を調べるか、イントロスペクションを使用してクラスがどのメソッドに応答するかを調べることができます。イントロスペクションを使用してカウンタキャッシュを自動的に実装するために、ActiveRecordで定義されたコールバックを調べる方法の例を示します。
ActiveRecord :: Base(this example comes from the test suite with Rails)に由来するReplyクラスを基にしたSpecialReplyというクラスがあるとしましょう。コンソールで
class SpecialReply < ::Reply
belongs_to :special_topic, :foreign_key => 'parent_id', :counter_cache => 'replies_count'
end
、あなたはあなたのクラスが.methods
を使用してに反応するものを見ることができます方法:以下に定義するように、それはカウンターキャッシュ列を持っています。これはObject
のすべてのインスタンスが既にメソッドの多くに対応しているので、多くのノイズを生成するために起こっているので、次のようにリストを絞り込むことができます。
1.9.3-p194 :001 > sr = SpecialReply.new
1.9.3-p194 :002 > sr.methods - Object.methods
をあなたが言っている二行目、ショーで私のSpecialReplyのインスタンスが応答するメソッドのすべてを、すべてのオブジェクトが応答するメソッドから除外します。これは、あなたが見ているクラスタイプに特有ではないメソッドを除外することで、イントロスペクションに役立ちます。
残念ながら、このフィルタリングの後でさえ、ActiveRecordがすべての子孫クラスに追加するメソッドのために、多くのノイズが発生します。この場合、grep
は便利です - ActiveRecordのが親切文字列counter_cache
(see the meta-programming used by ActiveRecord to generate a counter cache method for a belongs_to
association)を含むカウンタコールバックメソッドを作成するので、あなたは次のようにキャッシュに対抗するために関連する定義されたコールバックを見つけることができます:grep
以降に動作することを
1.9.3-p194 :001 > sr = SpecialReply.new
1.9.3-p194 :002 > sr.methods.map(&:to_s).grep(/counter_cache/)
お知らせ文字列であり、methods
はシンボルメソッド名の配列を返します。最初にto_proc
(&:
)を使用して、すべてのシンボルを文字列に変換してから、counter_cache
を含むシンボルをグレープします。それは、彼らはおそらく、自動生成のActiveRecordによるカウンタのキャッシュを実装するためのコールバックとしてだったように思える次の方法で私を残します:
belongs_to_counter_cache_after_create_for_special_topic
belongs_to_counter_cache_before_destroy_for_special_topic
belongs_to_counter_cache_after_create_for_topic
belongs_to_counter_cache_before_destroy_for_topic
belongs_to_counter_cache_after_create_for_topic_with_primary_key
belongs_to_counter_cache_before_destroy_for_topic_with_primary_key
あなたが追加したメソッド名を決定するために、あなたのプログラムで同様のプロセスをたどることができるはずですActiveRecordによって、existing instructions for removing callbacksの後にそれらをノックアウトできるようにします。
上記のオプションからの選択は、プログラムの構造と、データの読み込み効率の向上を考慮するトレードオフによって決まります。最初の2つのオプションは、クラスの動作を外部から変更することでコードを読みにくくすることができ、データの更新時にビジネスルール(キャッシュ列の更新)をバイパスすることでシステムを不安定にする可能性があります。このような理由から、データの可読性やデータの一貫性への影響を最小限に抑えながら、最適化された方法でデータをロードするための別のクラスを作成できるかどうかについて考えています。
これを解決しましたか?同じ問題... –