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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42765370/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 15:33:07  来源:igfitidea点击:

Laravel eloquent static boot deleting multiple relationship

laraveleloquent

提问by Keannu Alforque Atilano

I have this model that uses a static boot for deleting related models/tables in the db. First is the product model.

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

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

    static::deleting(function($product) {
        $product->hearts()->delete();
        $product->comments()->delete();
    });
}

It deletes the hearts and comments and it's working like a charm. But the problem is I have this reply model that has an relationship with my comment model and that reply model is being referenced from the comment model

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

public function replies()
{
    return $this->hasMany("App\Reply");
}

Then in my comment model I used another static boot for "Chaining" the boot delete from the product

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

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

    static::deleting(function($comment) { 
        $comment->replies()->delete();
    });
}

but it's not working. Can you guys give me an insight why this isn't working? Logically it should work because the comment is being deleted. Thank you.

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

回答by patricus

Inside your first deletingevent, you are calling $product->comments()->delete();. This line is actually calling the delete()method on a query builder object, and not the Commentmodels. Because no Commentmodels are created during the delete, the deletingevent on the Commentwill not be executed.

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

In order do to this type of application level cascading deletes, you will need to make sure that delete is only ever called on Commentinstances. You an either loop through the related records and delete them, or get a list of their ids and use the destroy()method (which does a loop behind the scenes):

为了执行这种类型的应用程序级级联删除,您需要确保仅在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);
});

Having said all that, if you have simple relationships and access to modify the database, you'll probably want to setup database level cascading deletes. This will be much faster than application level cascading deletes, as you won't need to load every model for every record to delete.

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

However, if you're in a situation where you need application level cascading deletes (e.g. polymorphic relationships, application architect requires them, etc), I do have a package that takes care of this for you: shiftonelabs/laravel-cascade-deletes. You just add a trait to your model and define the array of relationships to cascade delete, and you don't need to worry about anything else.

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