laravel Laravel中一对多删除相关模型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27274047/
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 10:30:29  来源:igfitidea点击:

Deleting related models one-to-many in Laravel

phplaravellaravel-4

提问by Nikola Sicevic

Is this even possible? In every tutorial that I read there is nothing about deleting, only selecting and inserting related models.

这甚至可能吗?在我阅读的每个教程中,都没有关于删除的内容,只有选择和插入相关模型。

This is my problem:

这是我的问题:

I have three levels of nesting. I have classes Package, Level, Lesson and Phase, and their models are below. First one - packages:

我有三级嵌套。我有课程包、级别、课程和阶段,它们的模型如下。第一个 - 包:

class Package extends Eloquent  {

protected $table = 'packages';
public $timestamps = false;

public function levels(){
    return $this->hasMany('Level', 'package_id');
}

}

}

Levels:

级别:

class Level extends Eloquent  {

protected $table = 'levels';

public function lessons(){
    return $this->hasMany('Lesson', 'level_id');
}

public function package(){
    return $this->belongsTo('Package', 'package_id');
}

}

}

Lessons:

课程:

class Lesson extends Eloquent {

class 课程扩展了 Eloquent {

protected $table = 'lessons';

public function phases(){
    return $this->hasMany('Phase', 'lesson_id');
}

public function level(){
    return $this->belongsTo('Level', 'level_id');
}

}

}

What I'm trying to do here is to when deleting one package i delete all levels related to it and also to delete all lessons related to those levels.

我在这里要做的是在删除一个包时删除与其相关的所有级别,并删除与这些级别相关的所有课程。

I have tried couple of options and they were all wrong, I just don't know how to do this without making a bunch of queries in foreach loop. Please, give some advice I'm so desperate I'm thinking about tweet to Jeffrey Way and ask him for the solution :) Thanks in advance

我尝试了几个选项,但它们都错了,我只是不知道如何在 foreach 循环中进行大量查询。请给一些建议,我非常绝望,我正在考虑给 Jeffrey Way 发推文,并向他寻求解决方案:) 提前致谢

回答by edpaez

You can approach this in two ways:

您可以通过两种方式解决此问题:

  1. Leverage the database to do the deleting for you. You'd add something like this to your migrations for the lessons, levelsand packages, respectively:

     $table->foreign('level_id')->references('id')->on('levels')->onDelete('cascade');
    
     $table->foreign('lesson_id')->references('id')->on('lessons')->onDelete('cascade');
    
     $table->foreign('package_id')->references('id')->on('packages')->onDelete('cascade');
    
  2. You can overwrite the deletemethod on each model to delete all of its relationships:

    class Lesson extends Eloquent {
    
        protected $table = 'lessons';
    
        public function phases(){
            return $this->hasMany('Phase', 'lesson_id');
        }
    
        public function level(){
            return $this->belongsTo('Level', 'level_id');
        }
    
        public function delete()    
        {
            DB::transaction(function() 
            {
                $this->level()->delete();
                $this->phases()->delete();
                parent::delete();
            });
        }
    
    }
    
  1. 利用数据库为您做删除。您将分别在lessons,levels和 的迁移中添加类似的内容packages

     $table->foreign('level_id')->references('id')->on('levels')->onDelete('cascade');
    
     $table->foreign('lesson_id')->references('id')->on('lessons')->onDelete('cascade');
    
     $table->foreign('package_id')->references('id')->on('packages')->onDelete('cascade');
    
  2. 您可以覆盖delete每个模型上的方法以删除其所有关系:

    class Lesson extends Eloquent {
    
        protected $table = 'lessons';
    
        public function phases(){
            return $this->hasMany('Phase', 'lesson_id');
        }
    
        public function level(){
            return $this->belongsTo('Level', 'level_id');
        }
    
        public function delete()    
        {
            DB::transaction(function() 
            {
                $this->level()->delete();
                $this->phases()->delete();
                parent::delete();
            });
        }
    
    }
    

回答by Alexander Guz

I think you can use foreign keyswith drop cascadein your case. I haven't worked with Laravel's ORM yet, but there is a section in documentationthat describes how to create foreign keys in migration.

我认为你可以在你的情况下使用foreign keyswith drop cascade。我还没有使用过 Laravel 的 ORM,但是文档中有一个部分描述了如何在迁移中创建外键。

Or you can try the technique suggested in this answer. The idea is to override the deletemethod and force the deletion of related objects.

或者您可以尝试此答案中建议的技术。想法是重写delete方法并强制删除相关对象。