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

时间:2022-10-16 08:20:31

We are trying to detect the changes in Laravel related models at attribute level, as we have to keep audit trail of all the changes which are made via the application.

我们试图在属性级别检测Laravel相关模型中的更改,因为我们必须对通过应用程序进行的所有更改保持审计跟踪。

We can track the changes via isDirty method on the Eloquent model for single model that is not related to any other model, but there is no way that we can track the changes on the related eloquent models. isDirty doesn't work on related models attributes. Can some one please help us on this?

我们可以在单独的模型上使用isDirty方法来跟踪与其他模型无关的变更,但是我们无法跟踪相关的有意义模型上的变更。isDirty不处理相关模型属性。有人能帮我们一下吗?

Update to original question:

原始问题的更新:

Actually we are trying to track changes on the pivot table that has extra attributes as well defined on it. IsDirty method doesn't work on those extra attributes which are defined in the pivot table.

实际上,我们正在尝试跟踪具有附加属性的pivot表上的更改。IsDirty方法不能处理在pivot表中定义的那些额外属性。

Thanks

谢谢

1 个解决方案

#1


3  

As much I understand your question, It's can achieve through Model Event and some sort of extra code with current and relation model.

我很理解你的问题,它可以通过模型事件和一些额外的代码来实现。

Laravel Model Events
If you dont want to use any additional stuff, you can just use the Laravel Model Events (that in fact Ardent is wrapping in the hooks). Look into the docs http://laravel.com/docs/5.1/eloquent#events

拉拉维尔模型事件如果您不想使用任何其他东西,您可以使用拉拉维尔模型事件(实际上,这个事件是热情洋溢的)。看看文档http://laravel.com/docs/5.1/雄辩的#事件

Eloquent models fire several events, allowing you to hook into various points in the model's lifecycle using the following methods: creating, created, updating, updated, saving, saved, deleting, deleted, restoring, restored.

有说服力的模型触发几个事件,允许您使用以下方法将模型生命周期中的各个点关联起来:创建、创建、更新、更新、保存、保存、删除、删除、恢复、恢复。

Whenever a new item is saved for the first time, the creating and created events will fire. If an item is not new and the save method is called, the updating / updated events will fire. In both cases, the saving / saved events will fire.

每当第一次保存新项时,创建和创建的事件就会触发。如果一个项目不是新的,并调用save方法,则更新/更新事件将触发。在这两种情况下,保存/保存的事件都将触发。

If false is returned from the creating, updating, saving, or deleting events, the action will be cancelled:

如果从创建、更新、保存或删除事件中返回false,则该操作将被取消:

Finally, reffering to your question you can utilize the above approaches in numerous ways but most obviously you can combine it (or not) with the Eloquent Models' getDirty() api docs here method and getRelation() api docs here method

最后,请回答您的问题,您可以以多种方式使用上述方法,但最明显的是,您可以将其(或不)与有说服力的模型“getDirty() api docs here方法”和“getrelationship () api docs方法”相结合

It will work for example with the saving event.

例如,它将与保存事件一起工作。

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! 
});

Another Thought might help you. when you saving

另一个想法可能对你有帮助。当你拯救

save() will check if something in the model has changed. If it hasn't it won't run a db query.

save()将检查模型中的某些内容是否发生了更改。如果没有,它就不会运行db查询。

Here's the relevant part of code in Illuminate\Database\Eloquent\Model@performUpdate:

这是在illumin\ \ \数据库雄辩的\ model@穿孔pdate中的相关代码部分:

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

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

    return true;
}

The getDirty() method simply compares the current attributes with a copy saved in original when the model is created. This is done in the syncOriginal() method:

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

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

    $this->syncOriginal();

    $this->fill($attributes);
}

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

    return $this;
}

check model is dirty isDirty():

检验模型为dirty isDirty():

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

Or check certain attribute:

或检查特定的属性:

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

I did not check this code but hopeful to use as your answer by thoughts, if you have any confusion to deal such requirement or something need to optimize or change please let me know.

我没有检查这个代码,但是希望用你的想法作为你的答案,如果你有任何困惑来处理这样的要求或需要优化或改变的事情,请让我知道。

#1


3  

As much I understand your question, It's can achieve through Model Event and some sort of extra code with current and relation model.

我很理解你的问题,它可以通过模型事件和一些额外的代码来实现。

Laravel Model Events
If you dont want to use any additional stuff, you can just use the Laravel Model Events (that in fact Ardent is wrapping in the hooks). Look into the docs http://laravel.com/docs/5.1/eloquent#events

拉拉维尔模型事件如果您不想使用任何其他东西,您可以使用拉拉维尔模型事件(实际上,这个事件是热情洋溢的)。看看文档http://laravel.com/docs/5.1/雄辩的#事件

Eloquent models fire several events, allowing you to hook into various points in the model's lifecycle using the following methods: creating, created, updating, updated, saving, saved, deleting, deleted, restoring, restored.

有说服力的模型触发几个事件,允许您使用以下方法将模型生命周期中的各个点关联起来:创建、创建、更新、更新、保存、保存、删除、删除、恢复、恢复。

Whenever a new item is saved for the first time, the creating and created events will fire. If an item is not new and the save method is called, the updating / updated events will fire. In both cases, the saving / saved events will fire.

每当第一次保存新项时,创建和创建的事件就会触发。如果一个项目不是新的,并调用save方法,则更新/更新事件将触发。在这两种情况下,保存/保存的事件都将触发。

If false is returned from the creating, updating, saving, or deleting events, the action will be cancelled:

如果从创建、更新、保存或删除事件中返回false,则该操作将被取消:

Finally, reffering to your question you can utilize the above approaches in numerous ways but most obviously you can combine it (or not) with the Eloquent Models' getDirty() api docs here method and getRelation() api docs here method

最后,请回答您的问题,您可以以多种方式使用上述方法,但最明显的是,您可以将其(或不)与有说服力的模型“getDirty() api docs here方法”和“getrelationship () api docs方法”相结合

It will work for example with the saving event.

例如,它将与保存事件一起工作。

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! 
});

Another Thought might help you. when you saving

另一个想法可能对你有帮助。当你拯救

save() will check if something in the model has changed. If it hasn't it won't run a db query.

save()将检查模型中的某些内容是否发生了更改。如果没有,它就不会运行db查询。

Here's the relevant part of code in Illuminate\Database\Eloquent\Model@performUpdate:

这是在illumin\ \ \数据库雄辩的\ model@穿孔pdate中的相关代码部分:

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

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

    return true;
}

The getDirty() method simply compares the current attributes with a copy saved in original when the model is created. This is done in the syncOriginal() method:

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

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

    $this->syncOriginal();

    $this->fill($attributes);
}

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

    return $this;
}

check model is dirty isDirty():

检验模型为dirty isDirty():

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

Or check certain attribute:

或检查特定的属性:

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

I did not check this code but hopeful to use as your answer by thoughts, if you have any confusion to deal such requirement or something need to optimize or change please let me know.

我没有检查这个代码,但是希望用你的想法作为你的答案,如果你有任何困惑来处理这样的要求或需要优化或改变的事情,请让我知道。