Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
9
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

@zaramme

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

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


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

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
9
Help us understand the problem. What are the problem?