Laravel eloquent 静态启动删除多重关系

Kea*_*ano 6 laravel eloquent

我有这个模型,它使用静态启动来删除数据库中的相关模型/表。首先是产品型号。

 protected static function boot() {
    parent::boot();

    static::deleting(function($product) {
        $product->hearts()->delete();
        $product->comments()->delete();
    });
}
Run Code Online (Sandbox Code Playgroud)

它删除了心形和评论,它的作用就像一个魅力。但问题是我有这个回复模型与我的评论模型有关系,并且回复模型是从评论模型中引用的

public function replies()
{
    return $this->hasMany("App\Reply");
}
Run Code Online (Sandbox Code Playgroud)

然后在我的评论模型中,我使用了另一个静态启动来“链接”从产品中删除的启动

 protected static function boot() {
    parent::boot();

    static::deleting(function($comment) { 
        $comment->replies()->delete();
    });
}
Run Code Online (Sandbox Code Playgroud)

但它不起作用。你们能告诉我为什么这不起作用吗?从逻辑上讲,它应该可以工作,因为评论正在被删除。谢谢你。

pat*_*cus 8

在您的第一个deleting事件中,您正在调用$product->comments()->delete();. 这一行实际上是delete()在查询构建器对象上调用方法,而不是Comment模型。因为Comment删除过程中没有创建模型,所以不会执行deleting上的事件Comment

为了处理这种类型的应用程序级级联删除,您需要确保仅在Comment实例上调用删除。您要么遍历相关记录并删除它们,要么获取它们的 id 列表并使用该destroy()方法(在幕后进行循环):

// do a loop yourself
static::deleting(function($product) {
    foreach ($product->comments as $comment) {
        $comment->delete();
    }
});

// or, destroy all the ids
static::deleting(function($product) {
    $ids = $product->comments()->lists('id')->all();
    Comment::destroy($ids);
});
Run Code Online (Sandbox Code Playgroud)

说了这么多,如果您有简单的关系和修改数据库的权限,您可能希望设置数据库级级联删除。这将比应用程序级级联删除快得多,因为您不需要为要删除的每条记录加载每个模型。

但是,如果您处于需要应用程序级级联删除(例如多态关系、应用程序架构师需要它们等)的情况,我有一个包可以为您处理这个问题:shiftonelabs/laravel-cascade-deletes。您只需向模型添加特征并定义要级联删除的关系数组,您无需担心其他任何事情。