Cakephp3を使っていると頻出するassociation
指定について、特に孫associationを指定する場合の記法が意外と難しいのでまとめました。
パターン1. クエリビルダのcontain
CakePHP3をやっていると一番馴染み深いパターンではないでしょうか。
ただ、この書き方だけ知っていると、他ではまることも・・・。
'contain' => [
'Childs' => [
'GrandChilds',
'OtherGrandChilds'
]
...
]
パターン2. Entity->newEntity()
など
こちらが比較的はまりがちのパターンで、パターン1と同じように書いてしまうと、
孫アソシエーションがうまく働いてくれません。
特にエラーメッセージなども出ないので、孫エンティティの一括登録を諦めてしまう人もいるのではないでしょうか(私です)
該当するメソッドはこちらになります。(他にもありましたらコメントお願いします)
-
Entity->newEntity()
,patchEntity()
,save()
-
FormHelper->create()
のcontext=>validatorオプション
記法としては2種類存在します。
.
繋ぎで深い関連を指定するパターン
Users->newEntity($data, [
'associated' => [
'Childs' => [
'validate' => 'register'
],
'Childs.GrandChilds' => [
'validate' => 'register'
],
'Childs.OtherGrandChilds' => [
'validate' => 'register'
],
],
]);
ポイントとしては、
- 配列のネストではなく、
.
繋ぎで、より深い関連を指定する - テーブル名のネスト配列には
validate
を指定する(省略された場合にはdefaultValidator
が呼び出されます)
FormHelper->create()
のcontext=>validatorで書く場合はこんな感じになります。
$this->Form->create($user,[
'type' => 'post',
'url' => [
'action' => 'save',
'controller' => 'user',
],
'context' => [
'validator' => [
'Childs' => 'default',
'Childs.GrandChilds' => 'order',
'Childs.OtherGrandChilds' => 'order'
]
],
])
associated
オプションを入れ子で使用する
こちらは公式のデータの保存に書かれている方法です。
// 入れ子になったアソシエーション付きの新しいエンティティ
$articles->newEntity($data, [
'associated' => [
'Tags',
'Comments' => [
'associated' => ['Users']
]
]
]);
子エンティティの配列の中に、さらにassociated
オプションを指定する感じですね。
(試してないのですが、こちらの記法でFormHelper->create()
はどう書くのでしょう・・・。validatorのなかにassociatedを書くのでしょうか。
いかがでしょうか。個人的には .
区切りの記法のほうがネストが複雑にならず、シンプルに書けるイメージです。