CheeseCake:タグ検索

2009 年 1 月 14 日 水曜日

本日のピンポイント・コードリーディングはCheeseCake2のタグ検索。

HABTMで関連付けられているモデルでのタグ検索(一方のテーブルのカラムをキーにしてもう一方のテーブルのレコードを抽出する)方法ではまったので、CheeseCakeではどのようにタグ検索を実現しているか調べてみた。

タグ検索の方法

PhotoモデルとTagモデルはhasAndBelongsToMany(HABTM)で関連付けられています。

タグ検索は、2つのモデル間を結びつけるphotos_tagsを介して行いますが、CakePHP hasAndBelongsToManyでページング(SQL LIMIT)とかを設定するにもあるとおり、hasMany関連での検索と同じ方法ではデータを抽出することができません。

× $data = $this->Photo->findAll('Tag.id'=>$id);

↑ PhotoはTagをLEFT JOINしていないので、Tag.idでの条件指定はできない

それでは、CheeseCakeではどのようにタグ検索を行っているのでしょうか。
CheeseCakeでは、以下のようにquery文を発行してデータを抽出しています。

return $this->query(  'SELECT '.     $fields.',     COUNT(DISTINCT t.tag) AS uniques   FROM '.    $prefix.'photos Photo,'.    $prefix.'photos_tags pt, '.    $prefix.'tags t   WHERE     Photo.id = pt.photo_id    AND t.id = pt.tag_id    AND t.tag IN ("'.implode('", "', $tags).'")'.$conditions.'   GROUP BY     pt.photo_id   HAVING      uniques = '.count($tags).   'ORDER BY     Photo.created DESC   LIMIT '.$offset.', '.$limit);

上記のコードがPhotoモデルのpaginateアクションに記述されています。queryを発行する以外にも方法はありますが、他の方法と比べて自由度は高い。

Cakeのメソッドに頼るよりも、自分でクエリを作成したほうが容易く処理を実装できることもある、ということは覚えておきたい。

コメントをどうぞ

トラックバック

このエントリーのトラックバックURL:

http://www.bmoo.net/archives/2009/01/142059.html/trackback