РЕШЕНИЕ: Ищем более умный способ синхронизировать c и упорядочить записи в сводной таблице Laravel / Eloquent. - PullRequest
1 голос
/ 08 июля 2020

В моем приложении Laravel 5.1 у меня есть классы Page (моделируют веб-страницу) и Media (моделируют изображение). Страница содержит набор объектов Media, и эта связь поддерживается в сводной таблице media_page. В сводной таблице есть столбцы для page_id, media_id и sort_order.

Служебная форма на сайте позволяет администратору вручную связать один или несколько элементов мультимедиа со страницей и указать порядок, в котором элементы мультимедиа отображаются в Посмотреть. Когда форма отправляется, контроллер получает отсортированный список идентификаторов носителей. Связь сохраняется в методах store () и update () контроллера следующим образом:

[STORE] $page->media()->attach($mediaIds);

[UPDATE] $page->media()->sync($mediaIds);

Это работает нормально, но не позволяет мне сохранить sort_order, указанный в параметре запроса mediaIds. Таким образом, элементы мультимедиа всегда возвращаются в представление в том порядке, в котором они появляются в базе данных, независимо от того, как администратор вручную упорядочил их. Я знаю, как прикрепить дополнительные данные для сводной таблицы при сохранении одной записи, но не знаю, как это сделать (или если это вообще возможно) при передаче массива в attach () или syn c (), как показано выше.

Я вижу только следующие способы:

  • l oop по массиву, вызывая attach () один раз для каждой записи и передавая по текущему индексу счетчика как sort_order.

  • сначала detach () все ассоциации, а затем передайте массив mediaIds в attach () или syn c (). Дополнительным преимуществом было бы то, что он вообще устраняет необходимость в столбце sort_order.

Я надеюсь, что есть более простое решение, которое требует меньшего количества обращений к базе данных. Или я просто слишком много обдумываю и, на самом деле, выполнение l oop самостоятельно ничем не отличается от того, чтобы позволить Laravel сделать это дальше по строке, когда он получает массив?

[РЕШЕНИЕ] Я получил он работает путем изменения формы массива следующим образом. Он расширяет разделенный запятыми параметр запроса mediaIds и перебирает результирующий массив, назначая каждый идентификатор мультимедиа в качестве ключа в массиве $ mediaIds, устанавливая значение sort_order, равное положению ключа в массиве.

$rawMediaIds = explode(',', request('mediaIds'));
foreach($rawMediaIds as $mediaId) {
    $mediaIds[$mediaId] = ['sort_order' => array_search($mediaId, $rawMediaIds)];
}

И затем отсортировано по sort_order при извлечении связанного со страницей носителя:

public function media() {
    return $this->belongsToMany(Media::class)->orderBy('sort_order', 'asc');
}

1 Ответ

0 голосов
/ 08 июля 2020

Вы можете добавить данные в сводную таблицу во время присоединения или синхронизации, например:


$mediaIds = [
    1 => ['sort_order' => 'order_for_1'],
    3 => ['sort_order' => 'order_for_3']
];

//[STORE]
$page->media()->attach($mediaIds;

//[UPDATE]
$page->media()->sync($mediaIds);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...