CakePHPのcounterCacheを任意に更新する
CakePHPのcounterCacheに関するメモを残しておきます。
counterCacheについて
CakePHPにはcounterCacheという機能があります。アソシエーション先のモデルで save()または delete()を実行した時に、数値集計用のフィールドの値を増減するというものです。
以下に、具体例を挙げます。
Post belongsTo Authorという関係性だった場合を考えます。
1 2 3 4 5 6 7 8 9 10 11 12 | class Post extends AppModel { public $belongsTo = [ 'Author' => [ 'className' => 'Author', 'foreignKey' => 'author_id', 'conditions' => '', 'fields' => '', 'order' => '', 'counterCache' => true, ], ]; } |
上記の通り、アソシエーションの定義に '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
機能
- 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
以上です。