2015-09-14 71 views
3

我们试图在属性级检测Laravel相关模型的更改,因为我们必须对通过应用程序所做的所有更改进行审计跟踪。跟踪相关模型的数据库更改... Laravel 5.1

我们可以通过Eloquent模型上的isDirty方法跟踪与其他模型无关的单个模型的更改,但是我们无法跟踪相关雄辩模型的更改。 isDirty在相关模型属性上不起作用。有人可以帮助我们吗?

更新到原来的问题:

实际上,我们正试图追踪上有它,以及定义额外的属性数据透视表的变化。 IsDirty方法不适用于在数据透视表中定义的那些额外属性。

感谢

+0

每个模型都有自己的isDirty方法,但为什么不根据每个模型实现功能。还有一件事你需要通过' - > relations'来检查它的关系模型。 –

+0

你试图通过这种方式检测到什么类型的变化? CRUD? –

+0

实际上,我们试图跟踪具有额外属性的数据透视表上的更改,并对其进行了定义。 IsDirty方法不适用于在数据透视表中定义的那些额外属性。是的,我们正在检测CRUD更改,因为我们必须创建审计线索。 –

回答

3

至于多少,我明白你的问题,这是可以通过人体模特儿事件和某种额外的代码与当前和关系模型实现。

Laravel模型事件
如果你不想使用任何额外的东西,你可以只使用Laravel模型事件(其实阿特在钩包装)。看看到文档http://laravel.com/docs/5.1/eloquent#events

雄辩车型火的几个事件,让您使用以下方法挂接到各种 点模型的生命周期:创建, 创建,更新,更新,保存,保存,删除,删除, 恢复,恢复。

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

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

最后,reffering你的问题,你可以利用多种方式上面的方法,但最很明显,你可以用雄辩模式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\[email protected]

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 
} 

我没有检查这个代码,但如果您有任何疑惑来处理此类需求,希望能够将其用作思考的答案NT或需要优化或改变的东西请让我知道。