软删除保存的雄辩模型

时间:2015-11-11 15:02:30

标签: laravel model eloquent laravel-5.1 soft-delete

我有一个雄辩的模型,想跟踪随着时间的推移所做的每一个变化。我在模型上启用了软删除,该部分工作正常。

当我想保存模型时,我克隆它,删除原始模型并保存克隆。通过这种方式,我可以看到模型随时间的每一次变化。

我想做的是,在调用普通模型时,模型本身内置了模仿这种行为的逻辑 - > save()。

这可能吗?

2 个答案:

答案 0 :(得分:1)

当然,您可以使用事件来执行此操作。在您的模型上,例如:

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

    self::saving(function (Model $model) {
        if ($model->isDirty()) {
            // clone the $model here
        }
    });

    self::saved(function (Model $model) {
        if ($model->isDirty()) {
            // delete the model here
        }
    });
}

您会注意到我同时使用savingsaved个事件。我故意这样做,以便您可以在更新数据之前克隆模型(通过从数据库重新检索模型或使用模型中存储的原始数据),然后在更新模型之前不会删除模型。保存到数据库中,为您提供您尝试实现的模式。

但是,对于记录,我不喜欢这种版本的版本。您如何知道记录是否实际被删除或仅仅是历史项目?使用此方法考虑关系的变化也很困难。我更喜欢日志样式(您可以在其中保存已更改的值的序列化列表,并根据需要进行转换)。这将导致数据库本身中的数据更少(因为您理想情况下只保存已更改的列),更明确定义的数据结构,以及由多态关系管理的中央表中的所有已记录更新。

如果你想按自己的方式去做,我认为更好的方法是克隆模型并删除克隆。我认为,这种方式对用户的破坏性较小,因为ID等不会不断变化,并且可能对其他用户来说已经过时。无论如何,我更愿意做一个序列化列表。

答案 1 :(得分:1)

我喜欢Josh的回答,尤其是isDirty支票。我建议的一个主要变化是创建一个单独的数据库表和单独的模型。将表命名为_revisions后缀,然后您甚至可以建立关系以轻松获取该模型的修订。

例如,如果您的实体被称为Post,那么post_revisions表应该是相同的,除了引用原始模型的其他post_id列。

class PostRevision {
    protected $table = 'post_revisions';

    public function post() {
        return $this->belongsTo(Post::class);
    }
}

class Post {
    protected $table = 'posts';

    public function revisions() {
        return $this->hasMany(PostRevision::class);
    }
}

现在你的帖子表没有乱七八糟的修改