I perform a find to retrieve one entity and contain one of its associated entities, of which it hasMany.
The retrieved data looks like this in simple terms:
object(App\Model\Entity\Order) {
'id' => '67839',
'price' => (int) 100,
'payment_instalments' => [
(int) 0 => object(Cake\ORM\Entity) {
'id' => (int) 43150,
'order_id' => '67839',
'amount' => (int) 100
}
]
}
I want to manually modify fields on the main entity and fields on the contained entity.
I can modify the main entity easily like this:
$order = $orders->patchEntity($order, [
'price' => 200
]);
The only way I could find of modifying the contained entity was to perform a separate patch on it. This can be done any number of ways. Here is one:
$instalments = TableRegistry::get('PaymentInstalments');
$instalment = $order->payment_instalments[0];
$order->payment_instalments[0] = $instalments->patchEntity(instalment , [
'amount' => 200
]);
Then I want to save all:
$orders->save($order, ['associated' => 'PaymentInstalments']);
The problem is the associated data does not get saved , and the reason is because $order->payment_instalments
does not get marked as "dirty" because it was patched separately. So the only solution I found was to manually mark it as dirty:
$order->dirty('payment_instalments', true);
Then the save will work.
This seems pretty messy to me, and would get a lot messier if I had to patch multiple contained entities. I couldn't find any documentation or help anywhere about how this is supposed to be done properly/elegantly.
Is there a way to modify both the main entity and contained entities in one go, and have it automatically recognise that the contained data is dirty?
$order = $orders->patchEntity($order, [
'price' => 123, // Change data on the order itself
'payment_instalments' => [
0 => [
'id' => 43150,
'amount' => 123,
]
]
]);
The 0 =>
part is optional, of course, in this case. I've put it in there to make it more clear that the data is in a nested array.
The reason why it's only saving the order itself and not the associated record is here:
'[dirty]' => [
'price' => true
],
payment_instalments
needs to be marked as dirty as well. That should happen automatically when you patch correctly.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.