CakePHPのcounterCacheを任意に更新する

Pocket

CakePHPのcounterCacheに関するメモを残しておきます。

counterCacheについて

CakePHPにはcounterCacheという機能があります。アソシエーション先のモデルで save()または delete()を実行した時に、数値集計用のフィールドの値を増減するというものです。

以下に、具体例を挙げます。
Post belongsTo Authorという関係性だった場合を考えます。

上記の通り、アソシエーションの定義に 'counterCache' => trueを追加します。また、 authorsテーブルに post_countというフィールドを追加します。
以上のように設定しておくだけで、 Postに対して、 save()または delete()が実行されると、自動的に authors.post_countが増減されるようになります。

集計用のフィールド名を変更したり、集計の条件を変更することも可能です。詳しくは、以下のリンクを参照してください。
counterCache – count()結果をキャッシュする – CakePHP Cookbook 2.x ドキュメント

belongsToアソシエーションに設定を行うので、合わせて以下のリンクも参照すると良いでしょう。
belongsTo – CakePHP Cookbook 2.x ドキュメント

counterCacheの値を任意に更新する

非常に便利なCakePHPのcounterCacheですが、数値が正常にカウントできない、数値がずれてしまうケースが存在します。

counterCacheの数値がずれてしまう原因として考えられるもの
  • データが存在しているモデルに対して、途中からcounterCacheを導入した
  • CakePHP以外からDB操作を行った

もちろん、上記のケースでも、その後に、 save()または delete()が実行されれば、正常値になります。
ただ、それでは不都合がありますので、好きなタイミングでcounterCacheの値を更新できるシェルを作りました。以下に公開します。
CakePHP-CounterCacheShell – GitHub

cakephp-counter-cache-shell-01
機能
  • counterCacheがtrueになっているモデル一覧を表示
  • 選択したモデル、または全モデルのcounterCacheをアップデート
使い方

ソースコードをダウンロードした後、 app/Console/Command以下に配置し、CLIで、 cake counter_cache updateを実行してください。対話形式でカウンターキャッシュを更新できます。

ToDo
  • オプションを取れるようにし、対話形式でなくても更新できるようにする
  • 日本語以外の言語にも対応する
コメント

中身は非常にシンプルで、 save()delete()の中でも呼ばれている Model::updateCounterCache()を呼んでいるだけです。Bakeや、Migrations Pluginあたりを参考に作りました。
公開するなら、プラグイン化した方が良いんでしょうか。ToDoに対するPull Requestも、お待ちしております。
CakePHP-CounterCacheShell – GitHub

以上です。

Pocket