CakePHPで関連テーブルを取得するSQLをカスタマイズ
アソシエーションを設定して、recursiveを指定すれば、自動的に関連テーブルを取得してくれるCakePHPですが、SQLの発行回数が増えていったりします。
明示的にLEFT OUTER JOINとか書いてSQLの発行回数を抑えたい!という場合、Modelの'finderQuery'を指定します。
UserモデルがReportをhasManyしていて、ユーザ毎のReport一覧を出す際にReportに対応するCustomerを取得したい場合、
自動的に取得するならUserモデルにはReportをこんな感じで指定。(更新日時降順の場合)
var $hasMany = array( 'Report' => array('className' => 'Report', 'foreignKey' => 'user_id', 'order' => array('modified' => 'desc'), 'counterQuery' => '' ),
SQLを指定する場合、finderQueryを書き換えます。
'finderQuery' => 'SELECT * FROM reports as Report LEFT OUTER JOIN customers as Customer ON Report.customer_id=Customer.id WHERE Report.user_id in ({$__cakeID__$}) ORDER BY Report.modified DESC',
{$__cakeID__$}が肝ですね。「=」でなく「in (...)」になっているのは、複数件を取得したとき(一覧など)はidひとつでなく複数が置き換わるためです。(例:「1,2,3」など)
本当にこのままのSQLを実行するので、ソート順やLIMITもSQL内に書かないと反映されませんし、pagination非対応です。(CakePHP1.1の場合。1.2は違うかも)