【问题标题】:Laravel 5 model deleting event ignoring attributes when soft deletingLaravel 5模型删除事件在软删除时忽略属性
【发布时间】:2016-03-09 13:22:29
【问题描述】:

我发现 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 方法不会进行此检查,因此不会将这些属性传递给构建器。虽然如果您在整个操作过程中查看堆栈,$this->model['attributes'] 具有我更改的 updated_at 属性!建造者只是从不使用它。

所以我猜我的问题是在不重写源代码的情况下,在使用软删除时如何将属性注入到 delete 方法中。就像在我的模型示例中一样。

这里的最终目标是在执行软删除时更新 updated_by 字段。我试图避免先更新表然后再删除。

【问题讨论】:

  • 那么您是说使用soft_deletes 时不会触发'deleting' 事件?这听起来像是一个可能的错误......
  • 不,它正在触发。我跟踪了每个操作,它获取了我的“删除”模型事件侦听器。问题出在 delete 方法中,它忽略了我在事件侦听器中设置的 updated_by 属性。

标签: laravel-5


【解决方案1】:

只需覆盖模型中的 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));
     }
}

【讨论】:

    【解决方案2】:

    我认为问题在于更新事件在事件之后调用了save() 函数,因此您所做的任何更改都将包含在save() 调用中。

    删除事件可能不会调用相同的 save() 函数 - 因此您的更改将丢失。

    尝试自己强制保存,看看是否有效?

        User::deleting(function($user)  {
            $user->updated_by = 1;
            $user->save();
        });
    

    【讨论】:

    • 是的,这就是我目前正在做的事情......先更新然后删除。我试图没有 2 笔删除交易。我修改了源代码并将提交一个拉取请求。谢谢
    猜你喜欢
    • 2018-06-18
    • 1970-01-01
    • 2016-03-05
    • 1970-01-01
    • 2022-01-20
    • 2015-10-06
    • 1970-01-01
    • 2014-08-12
    • 1970-01-01
    相关资源
    最近更新 更多