Php 自动删除Laravel 5.4(雄辩ORM)中嵌套的相关行
假设我有一本书。本书有章节,本书中的章节有分章 所以我有三个模型: 书籍>章节>分章 当我删除这本书($Book->delete();)时,我还想删除这本书的相关章节以及书中所有章节的相关子章节 在这里()我发现了一些有说服力的事件。无论何时删除一本书,在此之前,该章节都会被删除,因为我们将:Php 自动删除Laravel 5.4(雄辩ORM)中嵌套的相关行,php,laravel,laravel-5,laravel-5.4,Php,Laravel,Laravel 5,Laravel 5.4,假设我有一本书。本书有章节,本书中的章节有分章 所以我有三个模型: 书籍>章节>分章 当我删除这本书($Book->delete();)时,我还想删除这本书的相关章节以及书中所有章节的相关子章节 在这里()我发现了一些有说服力的事件。无论何时删除一本书,在此之前,该章节都会被删除,因为我们将: class Book extends Eloquent { public function chapters() { return $this->has_many('
class Book extends Eloquent
{
public function chapters()
{
return $this->has_many('Chapter');
}
protected static function boot() {
parent::boot();
static::deleting(function($book) {
$book->chapters()->delete();
});
}
}
所以我想,我只需要在我的章节模型中实现相同的代码,只需将“Book”与“Chapter”交换,“Chapter”与“Subchapter”交换:
当我删除一个章节时,这很好用。所有分章也将被删除
当我删除这本书时,它与章节配合得很好。所有章节也将被删除
然而,当我删除这本书时,它只删除章节。它不会删除已删除章节的相关分章
有人能帮我吗?这是因为
$book->chapters()
只会返回Builder
的实例。当您在生成器上调用delete()
时,它只需运行删除这些模型所需的查询,而不是新建模型,然后删除它们,这意味着章节
上的删除
事件将永远不会被触发
要解决此问题,您可以执行以下操作:
protected static function boot() {
parent::boot();
static::deleting(function($book) {
$book->chapters->each(function ($chapter) {
$chapter->delete();
});
});
}
希望这有帮助 正确的方法是使用。在
章节中
表迁移:
$table->foreign('book_id')
->references('id')
->on('books')
->onDelete('cascade');
$table->foreign('chapter_id')
->references('id')
->on('chapters')
->onDelete('cascade');
在子章中
迁移:
$table->foreign('book_id')
->references('id')
->on('books')
->onDelete('cascade');
$table->foreign('chapter_id')
->references('id')
->on('chapters')
->onDelete('cascade');
在这种情况下,您不需要编写任何代码,所有章节和子章节都将自动删除。这是因为当您同时删除多个对象时,不会触发每个模型的启动删除功能,因此您应该循环对象并逐个删除:
class Book extends Eloquent
{
public function chapters()
{
return $this->has_many(Chapter::class);
}
protected static function boot() {
parent::boot();
static::deleting(function($book) {
foreach($book->chapters as $chapter){
$chapter->delete();
}
});
}
}
/********************************/
class Chapter extends Eloquent
{
public function subChapters()
{
return $this->has_many(SubChapter::class);
}
protected static function boot() {
parent::boot();
static::deleting(function($chapter) {
foreach($chapter->subChapters as $subChapter){
$subChapter->delete();
}
});
}
}
但是,我的建议是设置表之间的级联外键关系,以便DBMS自动删除相关行,下面的示例代码向您展示了如何在迁移文件中执行此操作:
Schema::create('chapters', function (Blueprint $table) {
$table->increments('id');
$table->integer('book_id')->unsigned();
$table->string('title');
$table->timestamps();
$table->foreign('book_id')
->references('id')
->on('books')
->onDelete('cascade')
->onUpdate('cascade');
});
对子章执行相同操作。
希望它有助于……在RDBMS级别上实现这一点。尝试使用迁移选项(在级联删除中)尝试循环遍历各个章节,并逐个删除
foreach($book->chapters()->get()as$chapter){$chapter->delete();}
以及子章节foreach($chapter->subChapters()->get()->as$subChapter)中的相同内容{$subChapter->delete();}
谢谢,Ross。这很有意义。请在此处阅读更多信息:。但是,它对我不起作用:未定义的属性:illumb\Database\elount\Relations\hasmall::$each似乎无法识别“each->”.我忘了什么吗?@andydotlutz啊,很公平。如果是那样的话,我只会使用正常的each()
方法。我编辑了我的答案来反映这一点。这只适用于两个级别。@Muhammad在OP的问题中,章节
模型还有一个删除
挂钩。删除相关模型的方法取决于他们是想从数据库中删除行,还是需要挂接到E雄辩的事件。谢谢,托希德。重要提示:不要忘记“->未签名()!