例えば以下の2テーブルがあったとして・・・
ユーザの情報をもつユーザテーブル
users(Userモデル)
ユーザーがページを開くたびに保存されるログ(apacheのアクセスログみたいなものだと思ってもらえば)
もちろんuser_idというフィールドを持っている
user_logs(UserLogモデル)
このとき、User.idごとのページビュー(UserLogのレコード数)を取得したい場合はどうしますか?
僕の場合はコントローラで、
$bind = array(
"hasMany" => array(
"UserLog" => array(
"fields" => array("count(id) as pv"),
"conditions" => array("1 = 1 group by UserLog.id")
)
)
);
$this->User->bindModel($bind);
こんな感じで、取得していました。*1
でも、面倒だし、出力されるデータも
↓users = array(
"User" => // 省略
"UserLog" => array(
"0" => array(
// 省略
"UserLog" => array(
"0" => array(
"click" => // ここでやっとクリック数
)
)
)
)
);
すごく深くなってしまう。むだですよね。
counterCacheを使うと
usersテーブルに「user_log_count」*2 というフィールを追加。
UserLogモデルにbelongsToアソシエーションを追加して、counterCacheをtrueに
var $belongsTo = array(
"User" => array(
"counterCache" => true,
),
);
そうすると・・・
なんということでしょう!
UserLogにデータが追加されるたびにUser.user_log_countの数字がインクリメントされ、カウントが反映されます。
これでもうカウントを取得するためにUserLogをバインドする必要も無く、User単独でカウントが取得できるというわけ。
すごく便利でしょ!?
ちなみに
UserLogのレコードをdeleteしたらどうなるか?
UserLog.user_idを別のuser_idにupdateしたらどうなるか?
こういったことは検証していないので、もしやってみた方は教えていただけると嬉しいです。
コメント
この記事のおかげでモデルにSQL文書いたりして処理していたものがだいぶ省略できました。参考になる記事ありがとうございました