当属性是对象时,Laravel 模型事件不会更改属性值

问题描述 投票:0回答:1

我正在使用

Cknow/Money
包来处理模型中的货币值。

我有一个模型事件,可以在保存之前验证值,以防止由于常见情况而输入错误的数据:

我有这个 laravel 10 保存活动:

    static::saving(function (self $order) {
        if ($order->refunded_amount->greaterThan($order->total_amount)) {
            // Can't refund more than the order total.
            $order->refunded_amount = $order->total_amount;
            dd($order->refunded_amount); // This is still the original refunded_amount value instead of the new total_amount value
        }
    });

如果我在设置为

$order->refunded_amount
后检查
$order->total_amount
的值,该值仍然是错误的退款金额,就好像作业不知何故不起作用一样。

在模型上,这些都是铸造的:

protected $casts = [
    'total_amount'    => MoneyIntegerCast::class.':currency',
    'refunded_amount' => MoneyIntegerCast::class.':currency',
];

这只发生在 Eloquent 模型中的对象上。如果我有像

refund_count
total_count
这样的东西,并且两者都是整数,那么结果将是
refund_count
现在将等于预期的
total_count

Laravel v8 之后是否引入了某种模型级缓存?我不记得这是早期版本中的问题,但它发生在 v10 中。

laravel eloquent laravel-10
1个回答
0
投票

发生的事情是

refunded_amount
实际上并不是订单对象的属性。相反,当您请求此值时,Laravel 会从模型从数据库中水合时填充的
attributes
列表中提取它。

现在,当您执行

$order->refunded_amount = $order->total_amount
时,您实际上是在动态创建一个
refunded_amount
属性,这就是设置该值的地方。

相反,您想要修改模型属性列表中现有的

refunded_amount
,因为这将被保存。所以正确的做法是:
$order->attributes['refunded_amount'] = $order->total_amount;

© www.soinside.com 2019 - 2024. All rights reserved.