no-image

[教えてCakePHP]はびたむでBelongsToManyでの絞り込み

はびたむはマジで便利すぎて鼻血でるー!

という話を書こうと思ったのですが思うように動かなくてさじなげ。
以下のテーブルがあります。


CREATE TABLE article (
 id INTEGER NOT NULL PRIMARY KEY,
 title VARCHAR,  
 timestamp DATETIME ,
 content TEXT,   
 date DATE,
 format VARCHAR, 
 visible MEDIUMINT
);
CREATE TABLE category (
 id INTEGER PRIMARY KEY,
 code VARCHAR,   
 name VARCHAR,   
 visible INTEGER  DEFAULT '0'
);
CREATE TABLE category_list (
 id INTEGER  PRIMARY KEY,
 category_id INTEGER ,
 article_id INTEGER
);

これではびたむするわけです。モデルはこんな感じ。


class Article extends AppModel
{
   var $name = 'Article';
   var $useTable = 'article';
   var $hasAndBelongsToMany = array(
       'Category' => array(
           'className' => 'Category',
           'joinTable' => 'category_list',
           'conditions' => "", 
           'order' => '', 
           'dependent' => true,
           'foreignKey' => 'article_id',
           'associationForeignKey' => 'category_id',
           'unique' => false,
           'limit' => null,
       )   
   );  
}


class Category extends AppModel
{
   var $name = 'Category';
   var $useTable = 'category';
}

で、


$articles = $this->Article->findAll(null, null, 'date desc', 5); 

とすると、
「最新5件のエントリとそれにつけられた複数のタグ(システム上はcategoryという名前のもの)がとれる」
おおすごい!便利すぎる!

これはわかる。でも自分がしたいのはコレジャナイ。

「タグがmobileかmurmurのエントリ最新5件が欲しい」のです。

あー。今文章にして思ったけどこれはびたむの範囲じゃないね。やっぱ直でクエリうつしかないのかなー。

Cakeではびたむすると、クエリは2発発射される。最初の1回目でベースとなるデータを取得して、2発目でそこに付属するデータを取ってくる。なので、付属するデータを限定する事ができない。


SELECT "Article"."id", "Article"."title", "Article"."timestamp", "Article"."content", "Article"."date", "Article"."format", "Article"."visible"
  FROM "article" AS "Article" WHERE 1 = 1 ORDER BY "date" desc LIMIT 10

SELECT "Category"."id", "Category"."code", "Category"."name", "Category"."visible", "CategoryList"."id", "CategoryList"."category_id", "CategoryList"."article_id"
  FROM "category" AS "Category" JOIN "category_list" AS "CategoryList" ON (("CategoryList"."article_id" IN ('998', '997', '996', '995', '994', '993', '992', '991', '990', '989')) AND ("CategoryList"."category_id" = "Category"."id"))

いや、「付属するデータを限定する事だけ」ならできる。Modelの$hasAndBelongsToMany['Category']['conditions']がそれにあたるのだろう。しかし、ここで限定できるのは「一発目の結果」に対してなので、「タグがmobileかmurmur」に絞る事はできても、それを5件もってくる事ができないのだ。なぜなら1発目のクエリですでに5件に絞られてるから。
さらにいうと、「付属するデータしか限定できない」ので、最初のクエリでとった「タグがmobileでもmurmurでもない」エントリもデータ列として含まれる事になる。

で、ブログを読んでいるであろうケーキ職人に教えてもらおうと思ったんですが、今。まさに今。悩んでいるうちに解決方法を発見しましたよ!
答えは次のエントリで!