counterCache (HABTMでも)
カウンターキャッシュとは、hasManyしている関連Modelがあるとき、そのModelの件数を元Modelに保持しておく機能です。
http://book.cakephp.org/ja/view/81/belongsTo
たとえばArticle hasMany Comment というコメントを複数ぶらさげている記事があったとき、コメントの件数をArticle Modelに持たせることができます。
これによりわざわざコメントModelを取得することなく、コメントの件数を(記事一覧ページに)表示させるといったことが可能です。
データベースの構造からすると冗長なデータの持ち方ともいえますが、フィールドをひとつ増やすことでDBへのアクセスを減らすことが見込めますので、ぜひ積極的に活用したい機能です。
使い方は簡単です。
HABTMのcounterCacheは後述します。
まず、上記の例でArticleにあたるModelにフィールドを追加します。
- model_name_count integer
上記の例では comment_count です。
つぎに、関連先のModelのアソシエーションを以下のように変更します。
# models/comment.php var $belongsTo = array( 'Article' => array( 'counterCache' => true, 'counterScope' => '', ), );
これだけです。
これだけで、コメントがadd , edit ,delete されるたびに、紐付いたコメントの件数がArticleに書き込まれます。
実際にデバッグモードで発行されるSQL文を確認すると、insert等のあとにselect count(*) して、Articleをupdateしているのがわかります。
HABTMでcounterCacheを使う
さて、非常に簡単なcounterCacheですが、残念ながらHABTMでは使えません。
Article hasAndBelongsToMany Tag ※となっているとき、ArticleにはTagの件数を、TagにはArticleの件数を持っておきたいというのが人情です。
タグ(tag)付けされた、複数の記事(article)がある状況
そこで登場するのが、bakeryに投稿されたこのビヘイビア(CounterCacheHabtmBehavior)です。
このビヘイビアのすばらしいところは、それぞれのModelに xxx_count というフィールドを用意し、$actsAsで指定すれば、それだけで良いということです。
# model
// 両方のモデルに記述します
// カウントはxxx_countというフィールドが存在しているときのみ実行されます
var $actsAs = array('CounterCacheHabtm');
なお、片方のModelのみに xxx_count を用意した場合も、何の設定も必要なく、動作いたします。
(xxx_countが存在しない場合はカウントされません)