我在Laravel 5中发现令人费解的是它如何处理删除事件和任何已更改的属性。基本上,软删除只是对表上的deleted_at列的更新。我试图变得聪明,并且还包括进行删除的用户的用户ID。问题是删除方法在将更改的属性传递给查询构建器时忽略它们。
以此模型为例。
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model {
use SoftDeletes;
protected $table = 'users';
protected $fillable = [
'user_name', 'created_at', 'created_by', 'updated_at', 'updated_by', 'deleted_at'
];
public static function boot() {
parent::boot();
// This works and updates my updated_by column
User::updating(function($user) {
$user->updated_by = 1;
});
// This is being ignored and does not update the updated_by column
User::deleting(function($user) {
$user->updated_by = 1;
});
}
}
我已经跟踪了创建,更新和删除模型方法。在每种情况下,我的事件监听器都被拾取和处理。
在创建和更新保存方法中,存在差异。这两个方法都调用getDirty()方法,该方法查找已更改的属性并将数组传递给查询构建器。这就是插入或更新事件有效的原因。
但是delete方法不会执行此检查,因此不会将这些属性传递给构建器。虽然如果你在整个oprtation期间查看堆栈,$ this-&gt; model [&#39; attributes&#39;]有我更改的updated_at属性!建设者从不使用它。
所以我想我的问题是没有重新编写源代码,在使用软删除时如何将属性注入delete方法。就像在我的模型示例中一样。
此处的最终目标是在执行软删除时更新updated_by字段。我试图避免首先更新表然后进行删除。
答案 0 :(得分:2)
只需覆盖模型中的方法runSoftDelete
class User extends Model
{
protected function runSoftDelete()
{
$query = $this->newQuery()->where($this->getKeyName(), $this->getKey());
$this->{$this->getDeletedAtColumn()} = $time = $this->freshTimestamp();
$query->update(array($this->getDeletedAtColumn() => $this->fromDateTime($time), 'updated_by' => 1));
}
}
答案 1 :(得分:0)
我认为问题是更新事件会在事件发生后调用save()
函数,因此您所做的任何更改都将包含在save()
调用中。
删除事件可能不会调用相同的save()
函数 - 因此您的更改将丢失。
尝试自己强行保存并查看是否有效?
User::deleting(function($user) {
$user->updated_by = 1;
$user->save();
});