Laravel 观察者和 child/grandchild 关系

Laravel Observers and child/grandchild relationships

我不确定我是否只是误解了观察者在 Laravel 中的工作方式,或者我是否做错了什么。我目前 运行 在 Laravel 6,尽管此应用程序目前正在由另一个团队升级。

我有:

class Parent extends Model
{
    public function children()
    {
        return $this->hasMany( Child::class );
    }
}
class Child extends Model
{
    public function grandchild()
    {
        return $this->hasOne( Grandchild::class );
    }
}

我的两个观察者都在服务提供者中声明,并且都被成功调用。我的问题,或者可能是误解,是关于观察者如何互动的。

我的两个观察者都具有在收到删除命令时运行的功能。

class ParentObserver
{
    public function delete( Parent $parent )
    {
        $parent->children()->delete();
    }
}
class ChildObserver
{
    public function delete( Child $child )
    {
        $child->grandchild()->delete();
    }
}

ChildObserver 删除功能按预期 100% 工作。当我删除 child 时,grandchild 也会被删除。我感到困惑的是当我删除 Parent 时。 Parent删了,children删了,grandchildren没删。我没有直接调用删除 ParentObserver 中的 grandchildren,我期望 ChildObserver 功能会被 ParentObserver 中采取的操作触发。

我是不是在设置观察者的时候遗漏了什么?或者在观察者中采取的行动是否不会触发其他观察者,如果这些观察者在代码的另一部分中通常会参与这些行动?

这是一个批量删除查询。它不会为每个 Parent 的 children.

发出 deleted 事件
class ParentObserver
{
    public function deleted( Parent $parent )
    {
        $parent->children()->delete();
    }
}

如果你改成这样应该可以工作:

class ParentObserver
{
    public function deleted( Parent $parent )
    {
        $parent->children()->get()->each(function (Child $child) {
            $child->delete();
        });
    }
}

可能的改进:

  • cursor 方法已在 laravel 6 中实现,因此您可以使用它代替 get 以减少内存使用
  • 您可以使用 Higher Order Messageseach 方法来简化代码。
class ParentObserver
{
    public function deleted( Parent $parent )
    {
        $parent->children()->cursor()->each->delete();
    }
}

来自 Laravel 的文档:

When issuing a mass update or delete query via Eloquent, the saved, updated, deleting, and deleted model events will not be dispatched for the affected models. This is because the models are never actually retrieved when performing mass updates or deletes.

因此,如果您正在进行批量删除或批量更新,则不会触发。