跟踪相关模型的数据库更改... Laravel 5.1

3
我们正在尝试在属性级别上检测与 Laravel 相关的模型的更改,因为我们必须保留通过应用程序进行的所有更改的审计跟踪。
对于不涉及任何其他模型的单个模型,我们可以通过 Eloquent 模型上的 isDirty 方法来跟踪更改,但是我们无法跟踪相关联的 Eloquent 模型上的更改。isDirty 不能用于相关模型属性。请问有人能帮助我们吗?
原问题的更新:
实际上,我们正在尝试跟踪具有额外属性定义的中间表上的更改。IsDirty 方法无法在中间表上定义的这些额外属性上工作。
谢谢。

每个模型都有自己的isDirty方法,对吧,但为什么你不根据每个模型来实现功能呢?还有一件事,你需要通过->relations来检查它的关联模型。 - Safoor Safdar
你想要检测哪种类型的更改呢?CRUD操作吗? - Safoor Safdar
实际上,我们正在尝试跟踪具有额外属性定义的数据透视表上的更改。IsDirty方法无法在数据透视表中定义的这些额外属性上工作。是的,我们正在检测CRUD更改,因为我们必须创建审计跟踪。 - Farooq Khalid
这不是需要在数据库中的东西吗,比如一个触发器,将更改的行复制到只允许插入的表中?这可以跟踪数据更改,无论使用什么应用程序。(我喜欢帮忙,即使是旧问题) - Kwebble
1个回答

3
据我理解,您的问题可以通过模型事件和当前模型以及关联模型的某些额外代码来实现。 Laravel模型事件 如果您不想使用任何额外的东西,只需使用Laravel模型事件(实际上Ardent正在包装这些钩子)。请查看文档http://laravel.com/docs/5.1/eloquent#events 引用: Eloquent模型触发多个事件,允许您使用以下方法钩入模型生命周期中的各个点:creating、created、updating、updated、saving、saved、deleting、deleted、restoring、restored。 每当第一次保存新项目时,将触发创建和创建事件。如果项目不是新项目并且调用了保存方法,则将触发更新/更新事件。在这两种情况下,将触发保存/保存事件。 如果从创建、更新、保存或删除事件返回false,则操作将被取消。
最后,关于你的问题,你可以以多种方式利用上述方法,但最明显的是你可以将它与Eloquent模型的getDirty() api docs here方法和getRelation() api docs here方法结合使用(或不结合)。例如,在保存事件中使用它。
Model::saving(function($model){
    foreach($model->getDirty() as $attribute => $value){
        $original= $model->getOriginal($attribute);
        echo "Changed";
    }
    $relations  =  $model->getRelations();
    foreach($relations as $relation){
      $relation_model = getRelation($relation);
      foreach($relation_model->getDirty() as $attribute => $value){
        $original= $relation_model->getOriginal($attribute);
        echo "Relation Changed";
      }
    }
    return true; //if false the model wont save! 
});

另一个想法可能会对您有所帮助。当您保存时

save()将检查模型中是否有更改。如果没有更改,它不会运行数据库查询。

这是Illuminate\Database\Eloquent\Model@performUpdate中相关的代码部分:

protected function performUpdate(Builder $query, array $options = [])
{
    $dirty = $this->getDirty();

    if (count($dirty) > 0)
    {
        // runs update query
    }

    return true;
}

getDirty() 方法仅在模型创建时,将当前属性与保存在 original 中的副本进行比较。这是在 syncOriginal() 方法中完成的:

public function __construct(array $attributes = array())
{
    $this->bootIfNotBooted();

    $this->syncOriginal();

    $this->fill($attributes);
}

public function syncOriginal()
{
    $this->original = $this->attributes;

    return $this;
}

检查模型是否有更改 isDirty()

if($user->isDirty()){
    // changes have been made
}

或检查特定属性:

if($user->isDirty('price')){
    // price has changed
}

我没有检查过这段代码,但希望能够作为您的答案使用。如果您在处理此要求或需要优化或更改某些内容时有任何疑问,请告诉我。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接