CakePHPのアソシエーション設定時、'foreignKey' => falseが正しく処理されない
CakePHP 3.0.0 RC-1で起こっている。まぁ、安定版じゃないもんねぇ。
たぶん、一緒にconditionsを指定して独自の条件でアソシエーションを定義したいとき、勝手に外部キーを使われると邪魔くさいのでオフにしたい場合に使うことが多いだろう。
生成されたSQLを見る限り、where条件で`カラム名` = (ここに何も入らない)となってシンタックスエラー。勝手に生成されたSQLがシンタックス面で怒られてしまうというのはやっぱりフレームワークのバグなんだと思う。
'foreignKey'=>falseは安定版リリース後に使うとして、暫定対応としてはエンティティーにゲッターを定義することだろうか。
必要最低限の修正にするため、エラーの起こらないカラム名をforeignKeyに指定しておく。アソシエーション自体を消してしまうと、find時にアソシエーションがないっていうエラーが発生するので。 そうすると今度は余計なwhere条件が追加され、自分の想定したレコードが取ってこられない。
そこでエンティティークラスにアクセッサーを定義して、想定していないアソシエーションを無視した結果セットを取得しなおす。
アクセッサーの定義方法は以下。 http://book.cakephp.org/3.0/en/orm/entities.html#accessors-mutators
Lazy Loadingの解説も参照。 http://book.cakephp.org/3.0/en/orm/entities.html#lazy-load-associations というかやってることはまんまLazy Loading。
要は、_getXxxというゲッターメソッドを定義すれば、$entity->xxxというプロパティを参照しようとしたときに、実際に持っているxxxの値ではなくて_getXxxの戻り値が参照される。
_getXxxの中で、お好きなfindを実行すればOK。
ちなみにフォームヘルパーなど、持っている値を直接見に行ってしまう奴らにエンティティーを渡した際に、想定していない動きになる可能性があるので注意。 (注意ったってこっちはフォームヘルパーをオーバーライドして回避する程度の力技しか思いつかなかったけど)
バグが修正されたら、ちゃんと'foreignKey'=>falseに書き換える。 そしてエンティティーに作ったゲッターを削除する。これをやらないと結局ゲッターが優先されるので忘れずに。














