В моем приложении 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');
}