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
Deleting related models one-to-many in Laravel
提问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:
您可以通过两种方式解决此问题:
Leverage the database to do the deleting for you. You'd add something like this to your migrations for the
lessons
,levels
andpackages
, 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');
You can overwrite the
delete
method 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(); }); } }
利用数据库为您做删除。您将分别在
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');
您可以覆盖
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 keys
with drop cascade
in 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 keys
with drop cascade
。我还没有使用过 Laravel 的 ORM,但是文档中有一个部分描述了如何在迁移中创建外键。
Or you can try the technique suggested in this answer. The idea is to override the delete
method and force the deletion of related objects.
或者您可以尝试此答案中建议的技术。想法是重写delete
方法并强制删除相关对象。