gpt4 book ai didi

php - 以正确的顺序在保存时更新 Laravel Eloquent 增变器值

转载 作者:搜寻专家 更新时间:2023-10-31 21:28:08 25 4
gpt4 key购买 nike

假设我在一个表中有五个字段:price、cost、handling、shipping、profit

字段 shippingprofit 有变元,因为它们基于计算。

public function setShippingAttribute($value) {
$this->attributes['shipping'] = $this->attributes['handling'] + $value;
}

public function setProfitAttribute($value) {
$this->attributes['profit'] = $this->attributes['price'] - $this->attributes['shipping'] - $this->attributes['cost'];
}

我的问题有两方面,我正在努力为他们找出最优雅的解决方案:

  1. shipping 属性始终必须在保存期间首先调用它的 mutator,这样 profit 属性才会正确。

  2. 每次 pricecosthandling 属性发生变化时,我都需要 profit 和/或 shipping 属性也要更新(同样,以正确的顺序)。

我怎样才能有效地解决我的增变器的这两个问题?

注意:这是我对这个特定模型进行的计算的简化版本。实际上,其他 20 个示例中有这两个示例具有修改器,因此我需要我所做的一切都可以针对许多相互依赖的计算进行扩展。

最佳答案

为了解决这个问题并尽可能保持一切 self 维护,我不得不在这个模型上创建一个有点复杂的解决方案。以下是基于原始帖子的简化版本,供任何感兴趣的人使用,但它可以轻松扩展。

对于每个修改器,我创建了访问器以确保始终为每个新的数据请求完成计算:

public function getShippingAttribute($value) {
return $this->getAttribute('handling') + $value;
}

public function getProfitAttribute($value) {
return $this->getAttribute('price') - $this->getAttribute('shipping') - $this->getAttribute('cost');
}

访问器使用 getAttribute 方法而不是直接访问属性,以确保自动调用幕后的任何其他修改器或关系。

然后使用修改器来确保数据缓存在数据库中,以供将来针对它们的任何查询(这与仅附加数据相反):

public function setShippingAttribute($value) {
$this->attributes['shipping'] = $this->getShippingAttribute($value);
}

public function setProfitAttribute($value) {
$this->attributes['profit'] = $this->getProfitAttribute($value);
}

为了确保所有相关字段在发生变化时得到更新,我将其添加到模型中:

protected static $mutatorDependants = [
'handling' => [
'shipping'
],
'price' => [
'profit'
],
'cost' => [
'profit'
],
'shipping' => [
'profit'
]
];

protected $mutatorCalled = []; // Added to prevent unnecessary mutator calls.

如果上述任何字段发生更改,则在 saving 事件中自动重新计算它们的依赖项:

public static function boot()
{
parent::boot();

static::saving(function ($model) {
/** @var \Item $model */
foreach ($model->getDirty() as $key => $value) {
// Ensure mutators that depend on changed fields are also updated.
if (isset(self::$mutatorDependants[$key])) {
foreach (self::$mutatorDependants[$key] as $field) {
if (!in_array($field, $model->mutatorCalled)) {
$model->setAttribute($field, $model->attributes[$field]);
$model->mutatorCalled[] = $field;
}
}
}
}

$model->mutatorCalled = [];
});
}

按照它的结构,在上面的saving 方法中对setAttribute 的每次调用都应该级联下来触发所有其他相关的修改器。

如果我发现任何更新乱序,逻辑可能需要稍微调整一下,但到目前为止,它可以完成工作,并且如果我需要使用修改器添加更多字段,它是可扩展的。

关于php - 以正确的顺序在保存时更新 Laravel Eloquent 增变器值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33273865/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com