使用Laravel/Elount进行版本控制

使用Laravel/Elount进行版本控制,laravel,postgresql,Laravel,Postgresql,我有一个products表,它有一个序列id、一个sku、一个is_当前标志,然后是关于该商品的各种属性。它在sku上也有一个唯一的索引,其中_current=true以防止有多个当前记录 我想做的是,当您更改模型并调用save()时,会创建一个新记录,而现有记录只会更改为翻转is_current标志。因此,我想我需要的是一种方法,使用replicate()复制模型,放弃旧模型中的更改,只需更新以翻转当前标志false,然后插入新模型。大概是这样,虽然我可能没有想到,虽然100%。这可以作为“更

我有一个products表,它有一个序列id、一个sku、一个is_当前标志,然后是关于该商品的各种属性。它在sku上也有一个唯一的索引,其中_current=true以防止有多个当前记录


我想做的是,当您更改模型并调用save()时,会创建一个新记录,而现有记录只会更改为翻转is_current标志。因此,我想我需要的是一种方法,使用replicate()复制模型,放弃旧模型中的更改,只需更新以翻转当前标志false,然后插入新模型。大概是这样,虽然我可能没有想到,虽然100%。这可以作为“更新”事件的一部分在中完成吗?如果发生某些直接表更新,触发器是否是防止事故发生的更好选择?

您可以通过两种方式执行此操作,一种是挂接模型上的保存事件。另一个是在模型上创建新方法,我可能会选择新方法路线。比如
$product->updateCurrent()将执行所有逻辑

public function updateCurrent($details)
{
    $newProduct = $this->replicate()->fill($details);
    
    $this->update([
        'is_current' => false,
    ]);

    return $newProduct;
}
否则,保存事件将失败

<?php

namespace App\Events;

use App\Product;
use Illuminate\Queue\SerializesModels;

class ProductSaving
{
    use SerializesModels;

    public $product;

    /**
     * Create a new event instance.
     *
     * @param \App\Product $product
     */
    public function __construct(Product $product)
    {
        $this->product = $product;
    }
}
产品模型

protected $dispatchesEvents = [
    'saving' => \App\Events\ProductSaving::class,
];
产品保存事件

<?php

namespace App\Events;

use App\Product;
use Illuminate\Queue\SerializesModels;

class ProductSaving
{
    use SerializesModels;

    public $product;

    /**
     * Create a new event instance.
     *
     * @param \App\Product $product
     */
    public function __construct(Product $product)
    {
        $this->product = $product;
    }
}

查看。我尝试了此的事件版本,并立即在我的播种机中发现了一个错误,因为它对同一个模型进行了多次更新,从而导致历史记录丢失。我担心任何解决方案save()对于任何给定的雄辩模型都不能完全像预期的那样工作,因为事故会发生,丢失历史是一个灾难性的错误,因为它涉及到金钱计算。我想知道如果调用了save()并且is_current为false,是否应该重写模型中的save()以抛出错误?这似乎是一个笨拙的方法。有没有办法让$this成为新的记录?这就是为什么我说我会将它设置为自己的方法,破坏每个人都习惯的功能和可能在应用程序中的其他地方调用的功能是一个坏主意。同意,我最终使用pg触发器将历史记录分解成一个单独的表,因为这是防止意外删除历史记录的最安全的方法。我继续做了标记,因为它确实回答了我的问题。干杯