Laravel Eloquent ORM - много для многих удаляемых значений таблицы поворота

Используя Laravel, у меня есть следующий код

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

Review есть много-много отношений, определенных с объектом Product. Когда я удалю обзор, я ожидаю, что он будет отсоединен от связанных продуктов в сводной таблице, но это не так. Когда я запускаю приведенный выше код, я все еще вижу строку привязки в сводной таблице.

Я пропустил что-то здесь или так работает Ларавель? Я знаю метод 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');
    }
}

Заранее спасибо.

Ответ 1

Метод detach используется для освобождения отношения из сводной таблицы, в то время как удаление удаляет сама запись модели, то есть запись в таблице отзывов. Мое понимание заключается в том, что удаление не будет инициировать отсоединение неявно. Вы можете использовать события модели, чтобы вызвать очистку сводной таблицы, хотя, используя что-то вроде:

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

Кроме того, я бы предположил, что отношения будут от одного до многих, поскольку один продукт будет иметь много обзоров, но один обзор не будет принадлежать многим продуктам (обычно).

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');

Изменение: добавив ограничение, вы нажимаете очистку на базу данных и не должны беспокоиться о ее обработке в коде.

Ответ 2

Простые шаги:

В этом примере у 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');

Ответ 3

$review->product()->sync([]) также работает.

Однако $review->product()->detach() гораздо более явственно.