У меня много-много отношений. Модель Pivot имеет много детей. Когда я вызываю detach от многих ко многим, мне нужно также удалить дочерние модели модели. Я хотел использовать onDelete (‘cascade’), но это, похоже, не работает. Я также попробовал это: http://laravel-tricks.com/tricks/using-model-events-to-delete-related-items, но это тоже не работает. Ни один из них не работает, вероятно, потому что событие уничтожения не запускается.
Любые идеи о том, как я могу заставить детей удалять, когда я вызываю detach?
Вот мой код на случай, если я ошибся:
Моя основная модель:
Schema::create('beer_distributions', function(Blueprint $table)
{
$table->increments('id');
$table->integer('beer_id');
$table->integer('distributor_id');
Дети модели опоры:
Schema::create('kegs', function(Blueprint $table)
{
$table->increments('id');
$table->integer('beer_distribution_id');
$table->dropForeign('kegs_beer_distribution_id_foreign');
$table->foreign('beer_distribution_id')
->references('id')
->on('beer_distributions')
->onDelete('cascade');
Я не знаю, есть ли способ спасти этот подход. Я позвонил в sync и затем попытался удалить детей, не понимая, что родитель уже ушел, делая детей недоступными.
$attachments = $beer->distributors()->sync(Input::get('distributors'));
foreach ($attachments['detached'] as $distributor_id) {
BeerDistribution::where('beer_id', '=', $id)
->where('distributor_id', '=', $distributor_id)->first()->destroy();
}
ОБНОВИТЬ:
Просто чтобы прояснить, у меня есть четыре модели, с которыми я работаю. Пиво и дистрибьюторы со многими ко многим отношениям. Основная модель, BeerDistributions, имеет множество бочонков. Когда я вызываю синхронизацию для обновления дистрибьюторов пива, BeerDistributions действительно удаляются автоматически, и я хочу, чтобы кеги удалялись одновременно.
Вот некоторые из моих моделей:
class Beer extends Eloquent {
public function distributors()
{
return $this->belongsToMany('Distributor', 'beer_distributions');
}
Пиво много со своим дистрибьютором:
class Distributor extends Eloquent {
public function beers()
{
return $this->belongsToMany('Beer', 'beer_distributions');
}
Поворотная модель …
class BeerDistribution extends Eloquent {
public function kegs()
{
return $this->hasMany('Keg', 'beer_distribution_id');
}
имеет много бочонков:
class Keg extends Eloquent {
public function beerDistribution()
{
return $this->belongsTo('BeerDistribution');
}
Здесь, кажется, есть некоторая путаница в отношении сводных таблиц, отсоединения и каскадов.
По сути, метод отсоединения должен быть всем, что вам нужно для этого. Все, что он делает, это управление сводной таблицей через belongsToMany()
отношения.
Так что если вы делаете $keg->distributors()->detach([1,2,3])
а также $keg->id
значение 5, оно будет искать и удалять элементы из сводной таблицы, где распространитель равен 1, 2 или 3, а идентификатор кег — 5. В большинстве случаев вам даже не понадобится красноречивая модель для сводных таблиц. detach()
, attach()
, а также sync()
будет обрабатывать эту таблицу для вас.
Удаление на каскаде, скорее всего, вызывает у вас проблемы, потому что у тебя это задом наперед. В этом случае ключ удаления на каскаде будет помещен в сводную таблицу. Это означает, что при удалении родителя (кег или дистрибутив) те элементы, которые принадлежат этому родителю в сводной таблице, будут автоматически удалены. Это избавит вас от того, что в таблице появятся потерянные данные.
Почему я говорю, что вы делаете это задом наперед, потому что вы положили ключ на kegs
таблица, которая означает, что при удалении элемента в сводной таблице ваш кег также удаляется. Это плохо и совсем не то, что вы хотите. Вы хотите удалить элементы из сводной таблицы, когда ваша кег удаляется.
Удалите этот ключ и в вашей схеме, чтобы создать beerDistributions
добавить два ключа, которые будут выглядеть примерно так …
$table->foreign('beer_id')->references('id')->on('beers')->onDelete('Cascade');
$table->foreign('distribution_id')->references('id')->on('distributors')->onDelete('Cascade');
И если у вас есть ключ, который удаляется каскадно на столе вашего дистрибьютора, тоже удалите его. Должны быть только те внешние ключи на сводной таблице.
Изменить: Видя, как вы хотите удалить кеги, похоже, что вы ссылаетесь на неправильные столбцы в сводной таблице.
$table->foreign('id')
->references('beer_distribution_id')
->on('beer_distributions')
->onDelete('cascade');
Других решений пока нет …