web-dev-qa-db-ja.com

Laravel Eloquent ORM-多対多の削除されたピボットテーブル値

Laravelを使用して、私は次のコードを持っています

$review = Review::find(1);
$review->delete();

Reviewには、Productエンティティで定義された多対多の関係があります。レビューを削除すると、ピボットテーブルの関連製品から切り離されると予想されますが、そうではありません。上記のコードを実行しても、ピボットテーブルにリンク行が表示されます。

私はここで何かを見逃しましたか、これはLaravelが機能する方法ですか?detach()メソッドを知っていますが、エンティティを削除すると、関連するエンティティを自動的に。

Reviewは次のように定義されます:

<?php
class Review extends Eloquent
{
    public function products()
    {
        return $this->belongsToMany('Product');
    }
}

Productは次のように定義されます:

<?php
class Product extends Eloquent
{
    public function reviews()
    {
        return $this->belongsToMany('Review');
    }
}

前もって感謝します。

20
Grant J

Detachメソッドは、ピボットテーブルからリレーションシップを解放するために使用されますが、deleteはモデルレコード自体、つまりreviewテーブルのレコードを削除します。私の理解では、削除は暗黙的にデタッチをトリガーしません。ただし、 model events を使用して、ピボットテーブルのクリーンアップをトリガーできますが、次のようなものを使用します。

Review::deleting(function($review)
{
    $review->product()->detach()
}

また、1つの製品には多くのレビューがありますが、1つのレビューは多くの製品に属さないため(通常)、関係は1対多になることをお勧めします。

class Review extends \Eloquent {
    public function product()
    {
        return $this->belongsTo('Product');
    }
}

class Product extends \Eloquent {
    public function reviews()
    {
        return $this->hasMany('Review');
    }
}

もちろん、この場合、データベース構造を微調整する必要があります。あなたは、彼らがそうであるように、データベースの構造や、あなたの現在の関係を残すことを望んでいた場合は、他のオプションは、ピボットテーブルに外部キー制約を適用することであろうレビューや製品のいずれかが削除されたとき、あなたは上の削除をカスケード接続できることなピボットテーブル。

// Part of a database migration
$table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
$table->foreign('review_id')->references('id')->on('reviews')->onDelete('cascade');

編集:制約を追加する際に、クリーンアップ作業をデータベースにプッシュするため、コードでの処理を心配する必要はありません。

43
Michael Dyrynda

よりシンプルなステップ:

この例では、Accountには多くのTagsがあります:

タグを削除するには、[アカウントは、次の操作を行います。

// delete the relationships with Tags (Pivot table) first.
$account->find($this->accountId)->tags()->detach();

// delete the record from the account table.
$account->delete($this->accountId);

ピボットテーブルで-> onDelete( 'cascade');を持っていることを確認してください

$table->integer('account_id')->unsigned()->index();
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');

$table->integer('tag_id')->unsigned()->index();
$table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');
8
Mahmoud Zalt

$review->product()->sync([])も機能します。

ただし、$review->product()->detach()はより明示的です。

2
Kazuya Gosho