【问题标题】:Ignore the updated event when an Eloquent model is restored恢复 Eloquent 模型时忽略更新的事件
【发布时间】:2022-07-29 22:45:53
【问题描述】:

我正在构建一个 package 来记录 eloquent 上发生的更改,并且我正在尝试找出在 restored 时忽略 updated 事件的检查内容。

trait HasLogs
{
    public static function bootHasLogs(): void
    {
        // created ...
        self::updated(callback: fn ($model) => self::log($model, 'updated'));

        self::deleted(callback: function ($model) {
            // Ignore 'deleted' event when 'softDeleted' or 'forceDeleted'
            if (in_array('Illuminate\Database\Eloquent\SoftDeletes', (class_uses(self::class)))) {
                return;
            }
            self::log($model, 'deleted');
        });

        if (in_array('Illuminate\Database\Eloquent\SoftDeletes', (class_uses(self::class)))) {
            // softDeleted ...
            self::restored(callback: fn ($model) => self::log($model, 'restored'));
            // forceDeleted ...
        }
    }
    // ...
}

如果有帮助,这里是操作顺序:

  1. Model::restore() 在 SoftDeletes 特征上。
  2. ---- restoring 被解雇。
  3. ----Model::save()
  4. -------- saving 被解雇。
  5. -------- Model::performUpdate()
  6. ------------ updating 被解雇。
  7. ------------ Builder::update()
  8. ------------ updated 被解雇。
  9. -------- Model::finishSave()
  10. ------------ saved 被解雇。
  11. ---- restored 被解雇。

【问题讨论】:

  • 很确定您可以通过self::timestamps = false; 简单地禁用时间戳,如下所示:stackoverflow.com/questions/18904853/…
  • @TimLewis 只会避免在Model::performUpdate() 中调用Model::updateTimestamps()
  • 还有其他地方updated_at 被更改了吗?我还没有深入研究通过Model::restore() 调用的事件链,但我也没有遇到过我关心updated_at 是否通过restore 更改的情况????
  • @TimLewis Model::performDeleteOnModel() 来自SoftDeletes 不会触及timestamps,因为它直接调用Builder::update()。但是Model:restore() 通过Model::performUpdate()。
  • 我发现只有performUpdate和performInsert检查usesTimestamps()然后使用updateTimestamps()

标签: laravel events eloquent event-handling laravel-9


【解决方案1】:

特征HasLogs 为Model 添加了一个布尔属性,名为loggableIsBeingRestored,默认设置为false。

该特征还为restoring 注册了一个新的侦听器,该侦听器在所描述的操作请求时将loggableIsBeingRestored 设置为true。

然后updated 侦听器在继续其操作之前检查loggableIsBeingRestored。

trait HasLogs
{
    public bool $loggableIsBeingRestored = false;

    public static function bootHasLogs(): void
    {
        // ...

        self::updated(callback: function ($model) {
            if (isset($model->loggableIsBeingRestored) && $model->loggableIsBeingRestored) {
                // This is a restored event so don't log!
                return;
            }

            self::log($model, 'updated');
        });

        // ...

        self::restored(callback: function ($model) {
            self::log($model, 'restored');

            $model->loggableIsBeingRestored = false;
        });

        self::restoring(callback: function ($model) {
            $model->loggableIsBeingRestored = true;
        });
    }
    // ...
}

【讨论】:

    猜你喜欢
    • 2017-05-08
    • 1970-01-01
    • 1970-01-01
    • 2014-10-27
    • 1970-01-01
    • 1970-01-01
    • 2015-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多