尝试挂接到具有特征的模型 'updating' 事件

Trying to hook into Model 'updating' event with a trait

我正在尝试提供一种方法来跟踪用户何时更改我的应用程序中注释部分的模型。例如。 John 去修改了 2 个字段,将创建一条注释,说明 John 已将 title 从 'My title 1' 更改为 'My title 2' 并将 content 从 'Lipsum' 更改为 'Lipsum2'.

这是我创建的特征:

<?php

namespace App\Traits;

use Illuminate\Database\Eloquent\Model;

trait TrackChanges
{
    public $changes;

    public static function bootChangesTrait()
    {
        static::updating(function($model)
        {
            $this->changes = [];

            foreach($model->getDirty() as $key => $value)
            {
                $original = $model->getOriginal($key);

                 $this->changes[$key] = [
                    'old' => $original,
                    'new' => $value,
                ];
            }
        });
    }
}

而且我在我的模型上成功地使用了这个特性。但是,我不确定如何捕获更改的内容,或者它们是否正常工作。

在我的控制器中我有:

$site = Site::findOrFail($id);

// Catch and cast the is_active checkbox if it's been unselected
if ( ! $request->exists('is_active') )
{
    $request->request->add([ 'is_active' => 0 ]);
}

// // Get rid of the CSRF field & method
$data = $request->except([ '_token', '_method' ]);

$site->update($data);

我在 $site->update($data); 之前和之后尝试了 dd($site->changes),但它只是 returns null

我做错了什么?

您需要将特征中的启动方式更改为 bootTrackChanges()。要启动特征,您需要遵循 boot{TraitName} 的命名模式作为您的启动方法。然后,您需要将特征中的 $this 调用更改为 $model,以便将更改保存到模型中,因此您的特征应如下所示:

<?php

namespace App\Traits;

use Illuminate\Database\Eloquent\Model;

trait TrackChanges
{
    public $changes;

    public static function bootTrackChanges()
    {
        static::updating(function($model)
        {
            $changes = [];

            foreach($model->getDirty() as $key => $value)
            {
                $original = $model->getOriginal($key);

                 $changes[$key] = [
                    'old' => $original,
                    'new' => $value,
                ];
            }

            $model->changes = $changes;
        });
    }
}

另一件需要注意的事情是,如果你在你的模型中定义了一个引导方法,请确保你也调用了父引导方法,否则你的特征的引导方法将不会被调用,你的监听器也不会被注册..我由于忘记调用父方法,之前已经在这上面花了好几个小时。在您的模型中,不需要定义引导方法,但如果您确实像这样调用了父方法:

class MyModel extends Model
{
    use TrackChanges;

    protected static function boot()
    {
        // Your boot logic here

        parent::boot();
    }
}