CakePHP 2.x のPaginate + Joinでハマった話

まず、PagenateとJoinを同時に使う方法。

別途、functionの前にJOINの条件をpublic変数として設定しておく。

public $joins = array(
        array(
                'type' => 'left',
                'table' => 'hoges',
                'conditions' => array('hoges.ID = hogeID' )
        )
);

(テーブルhogesのIDと、こっちのテーブルのhogeIDを結合させている)

次に、paginateの中で先ほどのjoin設定を呼び出す。

$this->paginate=array(
      'Sample'=>array(
        'conditions'=>array('Sample.status'=>'active'),
        'joins'      => $this->joins,
        'fields'     => '*', 
      )
);
$data = $this->paginate('Sample');

無論これは、最初に変数として用意しなくても

$this->paginate=array(
      'Sample'=>array(
        'conditions'=>array('Sample.status'=>'active'),
        'joins'      => array(
                array(
                        'type' => 'left',
                        'table' => 'hoges',
                        'conditions' => array('hoges.ID = hogeID' )
                )
        'fields'     => '*', 
      )
);
$data = $this->paginate('Sample');

といった感じで書いても良い。好みの問題だが、あとで再利用したり見通しの良さを考えると、最初に変数として用意したほうがいいと思う。
これで、$dataの中にJOINされたデータが入ってくるので、あとは

$this->set('samples',$data);

といった感じで、Viewにデータを渡してあげるといい。

JOINしてるはずなのに向こうのテーブルの情報が入ってこない!

で、もう答えを書いてしまったんだけど、私がstuckしてしまった話。
「 ‘fields’ => ‘*’, 」
これがないと、ジョインする前のこちらテーブルのカラムしか呼び出さないので、SQL的にジョインはするものの、データが持ってこれない。

「 ‘fields’ => ‘*’, 」を指定しない場合のSQL

広告

SELECT `Sample`.`ID`, `Sample`.`name`, `Sample`.`hogeID`, `Sample`.`status`, `Sample`.`modified` FROM `gk_itweb_webreg`.`samples` AS `Sample` left JOIN `dacelo_space`.`hoges` ON (`hoges`.`ID` = `Sample`.`hogeID`)

「 ‘fields’ => ‘*’, 」を指定した場合のSQL

SELECT * FROM `gk_itweb_webreg`.`samples` AS `Sample` left JOIN `dacelo_space`.`hoges` ON (`hoges`.`ID` = `Sample`.`hogeID`)

もちろん*ではなくて明示的にこちらとJOIN先のカラムを指定してもいいけど、*でいいよね。楽だし。

About: dacelo


Leave a Reply

Your email address will not be published. Required fields are marked *