试图加入Model'更新'具有特征的事件

时间:2017-03-31 15:28:06

标签: laravel model eloquent traits

我试图提供一种方法来跟踪用户何时更改我的应用程序中的备注部分的模型。例如。约翰去修改了两个字段,会创建一个注释,说约翰已经更改了title来自我的标题1'到我的头衔2'和来自Lipsum'的content到' 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);

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

我做错了什么?

1 个答案:

答案 0 :(得分:3)

您需要将特征中的引导方法更改为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();
    }
}