【问题标题】:Laravel implement mutator with saveLaravel 用 save 实现 mutator
【发布时间】:2020-05-17 08:22:19
【问题描述】:

我正在编写一个 Product 模型,我希望能够通过 Product 模型更新产品的价格。由于产品的价格变化,我们需要保留价格历史,价格在自己的表中,有自己的模型。我可以通过从数据库中提取最近的有效日期行来找到产品的当前价格。

所以一个产品可以有多个价格,但一个价格只能有一个产品。

我在我的产品模型中将产品的“价格”公开为“单位价格”。显示/获取价格很容易。 getUnitPriceAttribute() 方法根据我的产品 ID 拉取最近的价格行,然后返回该行的价格。所以我可以做类似的事情

$some_var = $product_instance->unit_price;
echo $some_var;

并且模型按照您期望的方式工作。

我不知道编写setUnitPriceAttribute() 方法的正确方法。使用我目前的实现,如果我写类似

$product_instance->unit_price = 123;

然后代码将在价格表中添加一个值为 123 的新行。

如果在单个 Web 请求期间执行这些行,

$product_instance->unit_price = 1;
$product_instance->unit_price = 2;
$product_instance->unit_price = 3;

然后代码将向价格表中添加 3 个新行。在我为 Product 实例运行 save 方法之前,所有这些行都会被插入。

编写setUnitPriceAttribute() mutator 的正确方法是:

  1. 在有人运行产品的保存方法之前,不会将行插入到数据库中。

  2. 即使产品的价格在单个请求中多次更改,也只会将 1 行插入数据库。

  3. 更新产品价格后,您应该能够使用getUnitPriceAttribute() 方法获取新价格。

或者我不应该为此使用修改器和访问器吗?

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    protected $table = 'products';
    protected $fillable = ['title', 'description', 'unit_price'];

    protected $appends = ['unit_price', 'available_stock'];
    protected $with = ['prices', 'warehouse_product'];

    protected $hidden = ['prices', 'warehouse_product'];


    public function prices()
    {
        return $this->hasMany('App\Price');
    }

    public function setUnitPriceAttribute($new_price)
    {
        $this->prices()->create({
            'price' => $new_price
        });
    }

    public function getUnitPriceAttribute()
    {
        $price = $this->prices()->orderBy('created_at', 'desc')->take(1)->get();
        return $price[0]->price;
    }

【问题讨论】:

  • 在该请求中,您是否在getUnitPriceAttribute 方法的最新操作之后调用setUnitPriceAttribute?旁注:$price = $this-&gt;prices()-&gt;latest()-&gt;first();
  • @Tpojka 是的,我在 getUnitPriceAttribute 之后调用 setUnitPriceAtrribute。
  • 如果业务逻辑允许,解决方案 2 似乎没问题。在所有计算之后,在响应插入值之前。在不知道其他应用程序的参数的情况下无法说出更多信息,但这就是我的看法。

标签: php laravel model


【解决方案1】:

是的,因为您的 mutator 在您分配值的同时执行。如果您获得该保存的实例并使用该实例来创建该价格,则更好。例如:

$product = new Product
... assign your field to save in this instance

$product->save();

$product->insert([
   ['price' => 1],
   ['price' => 2],
   ['price' => 3]
]);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多