2012年11月2日金曜日

[CakePHP]$usesの謎

以下のようなアソシエイションの関係がある場合。

Theme hasAndBelongsToMany Tag
Tag hasAndBelongsToMany Theme
Tag hasMany ThemesTag
Theme hasMany ThemesTag
ThemesTag belongsTo  Theme
ThemesTag belongsTo Tag

 MainControllerというどのモデルの名前も使わない
コントローラーにて、
public $uses = array('Item','Tag','Theme','ThemesTag');

というように使用するモデルを指定した場合、問題が一つ起きる。

以下のような、HABTM関係の中間モデル、ThemesTagでのpaginate(もしかしたらfindも)にて
アソシエイション先のテーブルからデータをとってこない、という問題。
上記のアソシエイションの関係では、belongsToの関係を持つ、
ThemeとTagをJOINして持ってくると期待していたのに。
また、ThemeやTagの場合は期待通りアソシエイション先からデータを取得してくれる。
 $this->paginate('ThemesTag');

そこで、ためしに以下のように$usesで指定する順番を変えてみる。
 public $uses = array('ThemesTag','Item','Tag','Theme);

このように1番目にThemesTagを持ってくると期待通り、
アソシエイション先のテーブルからデータを取得してく れた。

次に、以下のようにThemesTagを2番目に指定したところ、
やはりだめだった。
 public $uses = array('Item','ThemesTag','Tag','Theme);

続いて、以下のようにpaginateの直前でbindModelを行ったところ、
アソシエイション先のテーブルからデータを取得してく れた。
$this->ThemesTag->bindModel(array('belongsTo'=>array('Theme','Tag')),false);

 【推論】
■中間テーブルは自モデルのコントローラでのみ、
 bindModel無しでアソシエイション先のテーブルからデータを取得する。
 ※自モデルのコントローラとは上記の例でいえば
     ・ThemesTagController。
     ・nameにThemesTagを指定したController 。
     ・どうやら以下のサイトによると$usesの先頭で指定したモデルが自モデルとなるらしい。
   Controller $uses への Model 名の登録順序
 

【結局どうするか】
$nameで中間テーブルを指定するのも変だし、
$usesで1番目を指定するというトリッキーなこともしたくないので、
bindModelをすることにする。

でも、なんで中間テーブルだけ違うのか謎だよなぁ。



0 件のコメント:

コメントを投稿