CakePHPのEntityの仕組みは、わかれば便利なんですが、知らないとちょっと困る場合が多いです。
patchEntity()を通してEntityを生成する場合は問題ないのですが、手動でEntityを書き換えた場合はいろいろハマるポイントがおおいですね。
いつもやり方を忘れてしまうので記事にしてみました。
バージョン
CakePHP3系およびCakePHP4系
問題点
usersとuser_profilesがHasOneであったとします。Entityの生成はこんな感じですね。
$userEntity = $this->Members->patchEntity($userEntity,$this->request->getData());
Entityのプロパティーを変えるときはこんな感じでEntity::set()メソッドをつかいます。
$userEntity->set('status',1); $userEntity->user_profile->set('hoge',1);
で問題はここから。
これでSaveしてもuser_profileの方の変更が保存されません。
なぜかというと、これだけでは変更が通知されていないから。
実は、内部でフィールドごとに変更があったかどうかのフラグがあって、そのフラグが立っていたら保存するというような処理になっています。
これはEntity::set()メソッドでプロパティーを書き換えたときにフラグが立ちます。
ですが、associatedされたテーブルに関してはアソシエーション元のフィールドの書き換えフラグが立っていませんので、更新されないのです。
解決策
ということで書き換えたよフラグを立てなければいけませんが、それにはEntity::setDirty()メソッドを使います。
こんな感じで。
こんな感じで。
$userEntity->setDirty('user_profile',true);
CakeBookにも一応書いてあるんだけど、いまいち意味が分かりにくいんですよね。というわけで記事にしてみました。
https://book.cakephp.org/3/ja/orm/entities.html
この仕様いつも忘れちゃって今まではpatchEntity()のところでどうにかしたり、いちいち調べたりしていて面倒だったので記事にしてみました。
Amazon.co.jp