開発中の CakePHP の案件でどうしても INNER JOIN する必要があり、かといって SQL を直接書くのは他のコンポーネントとの兼ね合いでできるだけ避けたい(というより無理)な状況だったので、絶対何か方法があるだろうと思いソースを調べたのでメモしておきます。

/cake/libs/model/model_php5.php の findAll メソッドに

$queryData = array('conditions' => $conditions,
    'fields'    => $fields,
    'joins'     => array(),
    'limit'     => $limit,
    'offset'    => $offset,
    'order'     => $order
);

というのがあり、’joins’ に 空の配列を入れている。
この ‘joins’ の使い方を調べたら、

array(
    "type" => "INNER",
    "alias" => "",
    "table" => INNER JOIN するテーブル,
    "conditions" => INNER JOIN の ONに指定する条件,
);

という配列を入れると INNER JOIN してくれるようです。

ただ、findAll の中で joins に空配列を入れているので、findAll を実行するときのパラメータに joins を指定しても無視されてしまう。
そこで、モデルの beforeFind メソッドを使用することにした。このメソッドは findAll の実行する前に呼ばれるメソッドです。

findAll を実行するモデルに次の beforeFind を定義

function beforeFind(&$queryData) {
    $queryData["joins"][] = array(
        "type" => "INNER",
        "alias" => "",
        "table" => "`model_name`",
        "conditions" => array("model_name.field=model_name2.field2"),
    );
    return true;
}

これで実行された SQL を確認すれば INNER JOIN されれいます。

関連する投稿