アソシエーションにあるけど今要らないデータはunbindModel

アソシエーションはあるけれどfindで別にツラツラデータが欲しくない場合、まず考えるのはrecursiveで階層指定することです。それだとうまく指定できない場合にはunbindModelを使います。CakePHP1.2.x.x_24.01.2008で確認してます。

//アソシエーションにあるけど今要らないデータはunbind
$this->unbindModel(array(‘hasMany’ => array(‘Mail’, ‘Pic’, ‘Post’)), false);

こんな感じに外したいモデルを指定します。
逆に付け加えたい場合にはbindModelを使います。具体例としては、関連キーで紐づいて引っ張られてくるデータの条件を一時的に付け加えたい場合等です。

//引っ張ってくるニックネームのstatus条件
$this->bindModel(array(‘hasMany’ => array(‘Nickname’ => array(‘conditions’ => array(‘status’ => ‘= active’)))), false);

こんな感じです。もともとのbelongtoやhasmanyに勝手にマージしてくれるので、追加したい条件だけ書けばOKです。

UserモデルがMail, Pic, Post, Profile, Nickname各モデルをhasmanyで持ってたとして、上記二つの指定をしたあとfindを使うと
$this->find(array(‘User.id’ => ‘= ‘.$id,));

  • Userモデルの中からidが$idのデータを取ってくる。
  • Mail, Pic, Post各モデルのデータは見に行かないからUserモデルのidに紐づいていても取ってこない。
  • Profileモデルはuserモデルのidに紐づいているデータをごっそりもってくる。
  • Nicknameモデルの中でuserモデルのidに紐づいているデータの中からさらにstatusがactiveなデータをとってくる。

ということが出来ます。

詳しい使い方はAPI for CakePHPやソースで確認してください。

プロフィール編集のコントローラーではUserモデルとUserモデルからそれに紐づいたProfileモデルとNicknameモデルだけ必要なのに、Userモデルに紐付けられてるPostモデルやPicモデルまでごっそり引っ張ってこられても邪魔です。この場合recursiveだけで深度をうまく設定することは出来ません。富豪的にごっそり呼び出して蓄えこんでもかまいませんが、それはあんまりだってことで自分なりにやり方を考えました。

はじめは、関連キーも変数なんだからいじっちゃえばいいのでは、ということでunset()を使うことを考えました。もちろんこれでも思い通りに動作します。findの前にunset($this->hasMany[‘Post’]);なんてやればアソシエーションがごっそり消せます。でもこれだと一時的に変更ではなく同じインスタンスの中だとその変更はずっとになってしまいます。もちろん自分でそうしたからですが。

何かいいやり方は無いかなとModelのAPI見ていると、そのまんま同じことをやっているメソッドがありました。unbindModelです。そりゃあるよね普通。一時的な変更にするかどうかも引数で設定できて一安心。それに加えてちょうど困っていた、紐づいて引っ張り出されてくるデータに条件を加えたい、という件まで逆のbindModelで解決しました。これで、必要に応じて必要なデータだけをとってくることが出来るようになりました。

上の例では外すのはモデル、付け加えるのは条件、としていますが当然それ以外もOKなはずです。でも例以外は試してません。

もう一点、本当は必要なアソシエーションだけbindModelでホワイトリスト式に動的に条件すべてをくっつけてやる方がよさそうな気もします。が、配列地獄で書くのがめんどくさいのでunbindModelでモデル名書くブラックリスト式にしてます。DBのテーブルが果てしなく増えてきたときにはホワイトリスト式を考えます。

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中