複数のテーブルを結合するアソシエーションという機能があります。
hasOne とか hasMany とか belongsTo とか HABTM とか。
通常はモデルにアソシエーションを定義しておくのですが、そのうちこの「あらかじめモデルにアソシエーションを定義しておく」という方法に限界を感じてきます。
「このメソッドでは関連テーブルのデータを全部ひっぱってきたいけど、このメソッドではいらない」的な。
そこでおすすめしたいのが、動的アソシエーション(ダイナミックバインド)です。
コントローラ内で必要に応じてアソシエーションを設定したり解除したりすることができます。
この動的なアソシエーションが有効となるのは、その直後に実行されるモデル操作に限定されます。
アソシエーションを動的に設定
$this->Model->bindModel($params, $reset);
アソシエーションを動的に解除
$this->unbindModel($params, $reset);
つまりこうなります↓
> コントローラ
$this->Group->bindModel(array( 'hasMany' => array('User'), ));
この動的なアソシエーションが使えれば、さらに先のレベルに進めること間違いなしですッ
意外と知られていない $reset パラメーターの落とし穴
Group と User があるとします。
User は Group に属しています。
Group のレコードを削除する時に、属する User のレコードも同時に削除したいとします。
> Group コントローラー
function delete($id = null) { $this->Group->bindModel(array( 'hasMany' => array( 'User' => array('dependent' => true), // 結合側のレコードも削除するかの真偽値 ), )); $this->Group->delete($id)); }
がしかし、これでは User のレコードが削除されないのです。
CakePHP のコアファイルを読んでみます。
> model.php
function bindModel($params, $reset = true) { // 省略 } function unbindModel($params, $reset = true) { // 省略 }
第2引数に $reset というものがあるではありませんか!!
$reset = 設定を維持的なものにする場合は true、変更する場合は false
ディフォルトでは $reset=true なので、find() などを行うと、動的なアソシエーション設定はリセットされてしまいます。
本来ならそれでいいのですが、一括削除ができないのはどうやらここに問題があるようです。
結論として、$reset パラメーターに false を渡せば解決ッ
function delete($id = null) { $this->Group->bindModel(array( 'hasMany' => array( 'User' => array('dependent' => true), ), ),false); $this->Group->delete($id)); }