在 Laravel 5.4 (Eloquent ORM) 中自动删除 NESTED 相关行

Myd*_*ame 3 php laravel laravel-5 laravel-5.4

假设我有一本书。这本书有章节,本书中的那些章节有子章节。

所以我有三个模型:

书籍 > 章节 > 子章节

当我删除这本书($book->delete();)时,我也想删除这本书的相关章节以及书中所有章节的相关子章节。

在这里(自动删除 Laravel (Eloquent ORM) 中的相关行)我发现了Eloquent Events。每当一本书被删除时,在此之前,章节会被删除,因为我们挂钩:

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();
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

所以我想,我只需要在我的章节模型中实现相同的代码,只需将“书”与“章”和“章”与“子章”交换:

class Chapter extends Eloquent
{
    public function subChapters()
    {
        return $this->has_many('SubChapter');
    }

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

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

当我删除章节时,这很好用。所有子章节也将被删除。

当我删除这本书时,它与章节一起工作正常。所有章节也将被删除。

但是,当我删除本书时,它只会删除章节。它不会删除已删除章节的相关子章节。

有谁能够帮助我?

Toh*_*had 5

那是因为当您同时删除多个对象时,它不会触发每个模型的引导删除功能,因此您应该遍历对象并逐个删除它们:

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();
        }
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

但是我的建议是在表之间设置级联外键关系,以便 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');  
    });
Run Code Online (Sandbox Code Playgroud)

对子章节做同样的事情。 希望能帮助到你...