Help us understand the problem. What is going on with this article?

CakePHP3のハマリどころ:孫associationを指定する記法はメソッドによって異なる

More than 3 years have passed since last update.

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を書くのでしょうか。


いかがでしょうか。個人的には .区切りの記法のほうがネストが複雑にならず、シンプルに書けるイメージです。

itpropartners
「自立」した人材を増やし、 "新しい仕事文化"をつくる」をテーマに、人材サービスを展開しているITプロパートナーズのエンジニアチームのOrganizationです。
https://itpropartners.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした