我正在使用
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 中。
发生的事情是
refunded_amount
实际上并不是订单对象的属性。相反,当您请求此值时,Laravel 会从模型从数据库中水合时填充的 attributes
列表中提取它。
现在,当您执行
$order->refunded_amount = $order->total_amount
时,您实际上是在动态创建一个 refunded_amount
属性,这就是设置该值的地方。
相反,您想要修改模型属性列表中现有的
refunded_amount
,因为这将被保存。所以正确的做法是:$order->attributes['refunded_amount'] = $order->total_amount;