今週末は紅葉を見に行こうと思っているんですが、台風が!
さて、ActiveRecord の標準機能 counter_cache はお手軽なんですが、『ちょいちょい Deadlock するよー』という Google の検索結果が気になります。「んー、このまま使って良いものか」と悩ましいところです。
カウントアップ/ダウンと値の参照は redis-objects の counter を使っちゃって、時々データベースにカウント値を同期して SQL で集計も出来るようにしてみたらどうかなーと思ったんでちょっと書いてみました。
別の記事を書きながら改めて動作確認したところ、sync_cache! 内に self.class.readonly_attributes.delete(dest) の追加が必要になることに気がついたので、追加してあります。この件につきましては別途記事にする予定。2014/12/05 追加(菊池)
app/models/concerns/redis_counter_cache.rb
これを使うには、モデルにちょっとした修正が必要になりますこんな感じに 〜_count がある方のモデルに include RedisCounterCache と counter_cache :〜_count を追加すると 〜_count_cache で redis-objects の counter が参照出来るようになります。
上のコードだと orders_count がデータベースに保存されている値で、orders_count_cache で redis-objects の counter を参照出来るようになります。
ということで、くどいんだけどこんな感じ
- 〜_count が元々のカウンター
- 〜_count_cache が redis-objects の counter を使ったカウンター
実際に使ってみると
このログとは別に Polymorphic Associations とも組み合わせて使ってみましたが、期待通りに動きました。
sync_cache! は定期的に動かしてもいいし、データ登録時に非同期のジョブを走らせてもいいかも。
ということで試作コードの紹介でした。
今週末の台風大丈夫かなー
菊池