CakePHPはいつJOINするのか

CakePHPについて、よく聞かれる質問のひとつに「関連づけられたModelが、JOINしたSQLを出してくれない」というのがあります。

結論をいうと、MySQLを使っているならば、CakePHPこちらが意識しないでJOINをしてくれるアソシエーションは hasOne と belongsTo だけです。

例えばhasManyの場合、2回SQLが呼び出されます。

mysql> select * from users\G
*************************** 1. row ***************************
      id: 1
username: User1
1 row in set (0.00 sec)

mysql> select * from profiles\G
*************************** 1. row ***************************
     id: 1
user_id: 1
   name: ProfileName1
1 row in set (0.00 sec)

[APP/models/user.php]

class User extends AppModel {
  var $name = 'User';
  var $hasMany = array('Profile');
}

[APP/models/profiles.php]

<?php
class Profile extends AppModel {
  var $name = 'Profile';
  var $belongsTo = array('User');
}

これで、consoleで、User->findById(1) をした場合、SQLは下記の2回実行されます。

SELECT `User`.`id`, `User`.`username` FROM `users` AS `User`   WHERE `User`.`id` = 1    LIMIT 1
SELECT `Profile`.`id`, `Profile`.`user_id`, `Profile`.`name` FROM `profiles` AS `Profile`   WHERE `Profile`.`user_id` = (1) 

これは、/libs/model/datasources/dbo_source.php の generateAssociationQuery() 関数あたりで精査されています。つまり、どのdboを使っているかによって変わる可能性があります

O/Rマッパーということで、どこまで気を使うかは、案配が少し難しいところです。

(動作確認は、CakePHP v1.3.11で行っています)