LoginSignup
9

More than 5 years have passed since last update.

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

Last updated at Posted at 2017-02-14

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


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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9