recursiveで悩むな、Containableを使え

CakePHPのModelが備える recursive 機能は分かりにくい上に効率が悪い。代わりにContainableビヘイビアを使うべき。今後新たに作り始めるならAppModelに次のように書いても良いくらい。

class AppModel extends Model {
    var $recursive = -1;
    var $actsAs = array('Containable');
}

このビヘイビアは、一言で言えば ActiveRecord(Rails) の include オプションのようなもの。一度の find で取得する関連を明示的かつ再帰的に指定することができる。

/*
Group hasMany User
  User hasOne Profile
*/
$rows = $this->Group->find('all', array('contain' =>
                                        array('User' => 'Profile')))

他にも取得する field を指定したり conditions を指定したりすることもできる。詳しくはCookbook和訳)参照。

ちなみにrecursiveの値そのものは、大まかには「(CakePHPのモデル実装が)追加で必要とするクエリの回数」を表しているものと思われる。そのルールそのものは Containable ビヘイビアを使ったとしても変わらない。すなわち belongsTo や hasOne のデータは基準となるテーブルにjoinして取得されるので追加のクエリは不要、よってrecursive=0。hasMany と hasAndBelongsToMany は追加で1回必要になるのでrecursive=1。recursive=2以降は…正直よく分からない(参考。2以降はルールが違うらしい)。Containableを使った方が絶対に良い。

Leave a Reply