Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 自动删除Laravel 5.4(雄辩ORM)中嵌套的相关行_Php_Laravel_Laravel 5_Laravel 5.4 - Fatal编程技术网

Php 自动删除Laravel 5.4(雄辩ORM)中嵌套的相关行

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('

假设我有一本书。本书有章节,本书中的章节有分章

所以我有三个模型:

书籍>章节>分章

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

在这里()我发现了一些有说服力的事件。无论何时删除一本书,在此之前,该章节都会被删除,因为我们将:

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雄辩的事件。谢谢,托希德。重要提示:不要忘记“->未签名()!