私の Rails 3 アプリには 2 つのモデルがあり、3 番目のモデルはモデルとモデルの間の結合テーブルであり、has_many 関係があります。基本的に、User と Show は SavedShow によって結合され、ユーザーがショーのリストを保存できるようにします。
class Show < ActiveRecord::Base
has_many :saved_shows
has_many :users, :through => :saved_shows
end
class User < ActiveRecord::Base
has_many :saved_shows
has_many :shows, :through => :saved_shows
end
class SavedShow < ActiveRecord::Base
belongs_to :user, :counter_cache => :saved_shows_count
belongs_to :show
end
counter_cache フィールド (shows_saved_count) は自動的にインクリメントされますが、デクリメントされないことに気付きました。この問題の核心は、ユーザーのリストからのショーの削除が delete によって行われ、counter_cache の更新がトリガーされないことにあるようです。
current_user.shows.delete(@show)
ただし、ここで destroy メソッドを呼び出すことはできません。これは、SavedShow の User/Show 関連付けを削除しただけでなく、Show オブジェクト自体も削除したためです。これは私が望んでいるものではありません。
この種のシナリオでの counter_cache は適切な用途ではありませんか?
これは 2009 年にバグとして議論されたようで、修正が議論されましたが、最新の Rails 3.0 でもまだ問題が発生しています。
モデルに独自のカスタム処理を記述するだけですが、フックできる after_delete コールバックがないようです (おそらく、これがデクリメントが最初に機能しない理由です)。現時点では、関連付けの削除が発生する可能性があるコード内の場所は 1 つだけなので、カウンターを更新するために手動で呼び出しを行いますが、これは counter_cache を使用した ActiceRecord 関連付けの根本的な欠点またはバグのようです。 、何かが足りないのではないかと思っています。
これが実際に counter_caches の真の問題である場合、最善の回避策は何でしょうか?