googleさんに multiple conditions columns join cakephp とかで調べても全然結果は出なかった。。。
以外と知られてない情報かもなという所で、共有と備忘録を兼ねて、残します。
他のモデルを結合 (JOIN) したい時に、複数のカラムを指定したい事があると思います。
例えば、同姓同名の別人を含むテーブルがあったとして
citizens
| prefecture | name | birthyear |
|---|---|---|
| Tokyo | 山田太郎 | 1990 |
| Tokyo | 名無し次郎 | 1988 |
| Wakayama | 山田太郎 | 1955 |
彼らからのコメントを保管するテーブルがあると
comments
| prefecture | name | comment |
|---|---|---|
| Tokyo | 山田太郎 | わしはいいとおもう |
| Wakayama | 山田太郎 | いかんでしょ |
(まあ、ビジネスキーをつけてれば何も問題ないのですが)、commentsテーブルの内容を select する時に、複数条件指定しないといけないわけです。
SQLだと、以下のような感じ
SELECT
citizens.prefecture,
citizens.name,
citizens.birthyaer,
comments.comment
FROM comments
LEFT JOIN citizens
ON citizens.prefecture = comments.prefecture
AND citizens.name = comments.name
まあ、 JOIN の条件を AND で結んで複数指定すると。
まあ、こういった事をする際に、当然かの有名なCakePHPならいい感じに書けそうに思えるんですが、これがXXXXXな事に、デフォでは対応してないんですね。
https://api.cakephp.org/3.6/class-Cake.ORM.Association.HasOne.html#_foreignKey
foreignKey の引数はガッツリ string です。
つーわけで、なんかしらやり方がないかと思ったら、以下の書き方でどうにかなりました。
(Tableのアソシエーションです。これ分からないならまずドキュメント読んでください)
(略)
use \Cake\Database\Expression\QueryExpression;
(略)
$this
->hasOne('Citizens', [ // まずここで一つだけ条件をセット
'foreignKey' => 'name',
'bindingKey' => 'name',
])
->setConditions([ // 上で指定した条件以外をココでセット。配列なので3つだろうが4つだろうがどんと来い
new QueryExpression('Citizens.prefecture = 'Comments.prefecture)
]);
(略)
SQLログも確認しましたが、いい感じにONに対してANDを繋いでいたので、問題なさそう。
(QueryExpression以外だと、WHEREで指定してるっぽい)