Laravel 5模型删除事件,在软删除时忽略属性

时间:2015-04-08 23:51:30

标签: laravel-5

我在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字段。我试图避免首先更新表然后进行删除。

2 个答案:

答案 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();
    });