在Laravel 4中,我有一个扩展Eloquent的类,我需要在保存时记录更改(保留历史记录)。
按预期调用在启动函数中保存事件。问题是:我如何知道哪些字段已更改并即将保存?另外,我可以在不重新加载记录的情况下访问现有值吗?
我知道,一种方法是再次加载记录并逐个比较所有字段。有没有更好的方法来做到这一点?
class Record extends Eloquent {
protected static function boot()
{
parent::boot();
static::saving(
function($record)
{
// It runs properly. This is where changes should be compared
return true;
}
);
}
}
谢谢。
答案 0 :(得分:9)
Eloquent的getDirty()
和getOriginal()
做了诀窍:
static::saving(
function($record)
{
$dirty = $record->getDirty();
foreach ($dirty as $field => $newdata)
{
$olddata = $record->getOriginal($field);
if ($olddata != $newdata)
{
// save changes from $olddata to $newdata
}
}
return true;
}
);
答案 1 :(得分:2)
我不认为接受的答案是最好的方法。为什么要遍历所有更改的字段以找出已更改的内容? Laravel有两种模型方法可以帮助你更好,
在保存功能/路线/控制器上,无论你使用哪个
$model::find(X);
...
'''
$model->fill(Input::all());
if( !empty($model->getDirty() )
// Get status of model. if nothing has changed there is no need to get in here
{
if($model->isDirty( { mixed data (array,string,null) } ))
// isDirty() will help you to find out if the field is different than original
{
.....
enter code here
....
}
}
答案 2 :(得分:0)
您可以使用活动:
Event::listen('saving', function($model)
{
// Do whatever you need to do with your $model before saving or not:
return true;
});
您还可以将该保存方法挂钩到任何控制器操作:
Event::listen('saving', 'LogThings@saving');
答案 3 :(得分:0)
我的项目中有类似的东西。
Record::updating(function($record){
$original = $record->getOriginal();
foreach($original as $index => $value){
if($index != 'updated_at' AND $index != 'created_at'){
if($value != $record[$index]){
RecordUpdate::create(array('record_id' => $record->id, 'fieldname' => $index, 'old_value' => $value, 'new_value' => $record[$index], 'created_at' => date('Y-m-d H:i:s')));
}
}
}
});
答案 4 :(得分:0)
您正在扩展的Eloquent类具有getOriginal()
和getAttributes()
方法,分别获取原始水合属性和当前设置的属性。
因此,在您的保存活动中,您可以执行类似......
的操作if ( ! empty( array_diff( $record->getOriginal(), $record->getAttributes() ) ) )
{
//log changes
}
如果您想对所有/大多数模型执行此操作,我建议将其抽象为通用Model Observer:
////
/* Subclassable, generic Model Observer */
////
class ModelObserver {
public function saving($model)
{
if ( ! empty( array_diff( $record->getOriginal(), $record->getAttributes() ) ) )
{
//log changes
}
}
}
////
/* Set up observers, for example in start/global.php */
////
$modelObserver = new ModelObserver;
Comment::observe($modelObserver);
Post::observe($modelObserver);
User::observe($modelObserver);