CakePHP 3 - 如何手动修补关联数据并保存所有数据?

时间:2017-01-27 02:26:46

标签: php cakephp cakephp-3.0

我执行一个find来检索一个实体并包含一个与之关联的实体,其实例有很多。

检索到的数据用简单的术语表示如下:

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
        }
    ]
}

我想手动修改主体上的字段和所包含实体上的字段。

我可以像这样轻松修改主体:

$order = $orders->patchEntity($order, [
    'price' => 200
]);

我能找到修改包含实体的唯一方法是在其上执行单独的修补程序。这可以通过多种方式完成。这是一个:

$instalments = TableRegistry::get('PaymentInstalments');
$instalment = $order->payment_instalments[0];
$order->payment_instalments[0] = $instalments->patchEntity(instalment , [
    'amount' => 200
]);

然后我要保存所有:

$orders->save($order, ['associated' => 'PaymentInstalments']);

问题是相关数据未保存,原因是$order->payment_instalments未被标记为“脏”,因为它是单独打补丁的。所以我找到的唯一解决方案是手动将其标记为脏:

$order->dirty('payment_instalments', true);

然后保存就可以了。

这对我来说似乎很混乱,如果我必须修补多个包含的实体,会变得更加混乱。我找不到任何关于如何正确/优雅地完成这方面的文档或帮助。

有没有办法一次修改主要实体和包含的实体,并让它自动识别包含的数据是否脏?

1 个答案:

答案 0 :(得分:2)

$order = $orders->patchEntity($order, [
    'price' => 123, // Change data on the order itself
    'payment_instalments' => [
        0 => [
            'id' => 43150,
            'amount' => 123,
        ]
    ]
]);

在这种情况下,0 =>部分是可选的。我已经把它放在那里,以便更清楚地表明数据是嵌套数组。

它只保存订单本身而非相关记录的原因在于:

'[dirty]' => [
    'price' => true
],

payment_instalments也需要标记为脏。当您正确修补时,这应该会自动发生。