1つの方法は、破棄の際にキャッシュカウントを更新する方法を一時的に無効にすることです。たとえば あなたは二つのモデル
class Category < ActiveRecord::Base
has_many :products
end
class Product < ActiveRecord::Base
belongs_to :category, counter_cache: true
end
を以下している場合今、あなたは
2.1.5 :038 > Product.new.methods.map(&:to_s).grep(/counter_cache/)
次これはcounter_cacheに関連するすべての製品のインスタンスメソッドを示してカウントキャッシュを更新する責任方法を見つけることを試みること、次のような結果メソッドの名前から
=> ["belongs_to_counter_cache_before_destroy_for_category", "belongs_to_counter_cache_after_create_for_category", "belongs_to_counter_cache_after_update_for_category"]
と、それは示してい
"belongs_to_counter_cache_after_create_for_category"
は、破棄後のカウンタキャッシュの更新を担当している可能性があります。 は、だから私は今
Product.class_eval do
def fake_belongs_to_counter_cache_before_destroy_for_category; end
alias_method :real_belongs_to_counter_cache_before_destroy_for_category, :belongs_to_counter_cache_before_destroy_for_category
alias_method :belongs_to_counter_cache_before_destroy_for_category, :fake_belongs_to_counter_cache_before_destroy_for_category
end
を(カウンタキャッシュの更新をスキップする)あなたはどんな製品オブジェクトを破壊するならば、それはカテゴリー内のカウンタキャッシュは更新されません一時的に何もしない1つの偽の方法でこのメソッドをオーバーライドすることにしました表。 しかし、コードを実行して特定のオブジェクトを破棄した後、実際のメソッドを復元することは非常に重要です。あなたは、特定のタスクを破壊した後、あなたは両方のオーバーライドを実行し、コード
を復元することを確認しますクラスのメソッドを、書くことができるメソッドの定義が常に復元することを確実にするために
Product.class_eval do
alias_method :belongs_to_counter_cache_before_destroy_for_category, :real_belongs_to_counter_cache_before_destroy_for_category
remove_method :real_belongs_to_counter_cache_before_destroy_for_category
remove_method :fake_belongs_to_counter_cache_before_destroy_for_category
end
を次の操作を行うことができ、実際のクラスメソッドに復元するには与えられたとして、あなたは
Product.without_counter_cache_update_on_destroy { Product.last.destroy }
以下いずれかの製品のオブジェクトを破壊する場合
class Product < ActiveRecord::Base
belongs_to :category, counter_cache: true
def self.without_counter_cache_update_on_destroy(&block)
self.class_eval do
def fake_belongs_to_counter_cache_before_destroy_for_category; end
alias_method :real_belongs_to_counter_cache_before_destroy_for_category, :belongs_to_counter_cache_before_destroy_for_category
alias_method :belongs_to_counter_cache_before_destroy_for_category, :fake_belongs_to_counter_cache_before_destroy_for_category
end
yield
self.class_eval do
alias_method :belongs_to_counter_cache_before_destroy_for_category, :real_belongs_to_counter_cache_before_destroy_for_category
remove_method :real_belongs_to_counter_cache_before_destroy_for_category
remove_method :fake_belongs_to_counter_cache_before_destroy_for_category
end
end
end
今では、カテゴリーテーブル内のカウンタキャッシュは更新されません。
参考文献:
無効化ActiveModelコールバックhttps://jeffkreeftmeijer.com/2010/disabling-activemodel-callbacks/ 一時的なオーバーライドメソッド:https://gist.github.com/aeden/1069124
あなたはすべてのコールバックをスキップしても大丈夫であれば、あなたは 'Model.firstを使用することができます。delete' –
コールバックをスキップする方法はわかっていますが、カウンターコールバックだけを無効にする必要があります。今のところ、私は 'destroy_all'を使っていて、カウンターをリセットしています(無駄に思えます)。 –