(Laravel) Как удалить несколько моделей, включая дополнительные отношения? - PullRequest
0 голосов
/ 18 февраля 2019

Сводка

Я пытаюсь разрешить моему контроллеру моделей удалить несколько моделей (выбранных массивом идентификаторов), включая их выбранных связанных моделей (выбранныхмассив имен отношений).

Ситуация

  • Модель Post со связями:

    • (один ко многим) сComment модель под $post->comments()
    • (один-ко-многим) с Image модель под $post->images()
    • (много-к-одному) с User модель под $post->user()
  • В PostController есть метод destroy_multiple, который обрабатывает удаление, и где у меня есть:
    • Массив $ids с идентификаторами Postмодели для удаления (например, [1,2,4])
    • Массив $related_models с именами отношений для удаления (например, ['user','comments'], но может быть другой выбор в каждом вызове)

Попытки

1) Повторять и удалять:

Post::findMany($ids)->each(function($item) use ($related_models) {
    foreach ($related_models as $relation) {
        $item->{$relation}()->delete();
    }
    $item->delete();
});

Проблема: Все моделидолжны быть найдены в первую очередь, и для каждой модели все выбранныеТед связанные модели должны быть удалены.Это много накладных расходов.

2) Удалить связанные модели и модели:

// For every selected relationship, delete related models
foreach ($related_models as $relation) {
    $class = 'App\\' . studly_case(str_singular($relation));
    $class::whereIn('post_id', $ids)->delete();
}

// Delete the models
Post::destroy($ids);

Проблема: Это работает только для отношений «один ко многим» и только при условии, что столбцы базы данных названы в соответствии со стандартом Laravel.

Вопрос

Какой самый эффективный способ сделать это, при этом:

  • с использованием определенных отношений для обеспечения правильного именования базы данных, столбцов и т. Д. (Как в Попытке 1)
  • сохранение производительности (без необходимости извлечения моделей) (как в Попытке)2)
  • с возможностью выбора $ids и $related_models

?

Примечания

  • Я знаю, что удаление родительской модели (User в данном случае) - не очень хорошая практика, но это ради вопроса.;)
  • Использование ограничения базы данных CASCADE на внешние ключи таблиц связанных моделей (при переносе) приводит к потере возможности выбора.Связанные модели теперь всегда удаляются, а также в других случаях, кроме метода delete_multiple.

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

Сначала вы должны удалить модели отношений

Добавьте этот метод в вашу модель Post:

public function delete()
{
    $this->images()->delete();
    $this->comments()->delete();

    return parent::delete(); 
}

Вызов из логики вашего контроллера Сначала будет удалена модель отношений, а затем удалена сама

Post::findMany($ids)->each(function ($item) {
        $item->delete();
    });
0 голосов
/ 18 февраля 2019

Вы можете обновить свою миграцию следующим образом:

Schema::table('comments', function (Blueprint $table) {
    ...
    $table->unsignedInteger('posts_id');
    $table->foreign('posts_id')
          ->references('id')
          ->on('posts')
          ->onDelete('cascade');
});

Вышеуказанная миграция автоматически удалит все комментарии, относящиеся к удаляемому сообщению.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...