TL;DR: beforeSaveでassociatedを書き換えるときは、ドット記法は使えないので配列で指定する。
Authors
hasMany Posts
hasMany Comments
のリレーションがあるとする。
Authorsから、Posts、Commentsをまとめてsaveしたい場合、通常のsaveであればassociated
に指定してやればよい。
1 2 3 4 |
$this->Authors->save($author, [ 'associated' => ['Posts.Comments'], ]); |
通常はこれでよいとして、特殊な要件により通常はPostsまでの保存で、あるときだけCommentsも保存すると言った場合、Model.beforeSave
イベントにフックしてassociatedを書き換えることを検討する。
単純に以下のコードでは動かない。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// Listenerクラスで public function beforeSave(Event $event, EntityInterface $entity, ArrayObject $options) { $table = $event->getSubject(); if ($table instanceof AuthorsTable) { $options['associated'][] = 'Posts.Comments'; } return true; } |
上記だと InvalidArgumentException : Cannot save Posts.Comments, it is not associated to Authors
と怒られる。
なぜならば associated
オプションはbeforeSaveに入る前に正規化されているため、ドット記法ではなく以下のように配列化しておく必要がある。
1 2 3 4 5 6 7 8 9 10 11 |
public function beforeSave(Event $event, EntityInterface $entity, ArrayObject $options) { $table = $event->getSubject(); if ($table instanceof AuthorsTable) { $options['associated']['Posts'][] = 'Comments'; } return true; } |