#laravel #thephpleague-fractal
#laravel #thephpleague-фрактал
Вопрос:
У меня есть это отношение:
У каждого пользователя есть галерея, а в галерее много файлов.
У двух пользователей может быть галерея с одинаковой датой.
Это выходной ответ JSON:
User1 {
galleries: {
created_at: 23.04.2019.
files: [
{
path: "path/to/file.jpg"
},
{
path: "path/to/file2.jpg"
},
]
}
},
User2 {
galleries: {
created_at: 23.04.2019.
files: [
{
path: "path/to/file3.jpg"
},
{
path: "path/to/file4.jpg"
},
]
}
}
Мне нужно как-то сгруппировать галереи по значению created_at, но сохранить все файлы в одном и том же ответе JSON для сгруппированного объекта galleries. Вот так:
Users {
galleries: {
created_at: 23.04.2019.
files: [
{
path: "path/to/file.jpg"
},
{
path: "path/to/file2.jpg"
},
{
path: "path/to/file3.jpg"
},
{
path: "path/to/file4.jpg"
},
]
}
},
Я пытался использовать ->groupBy('galleries.created_at')
, но что я получаю это — первый файл из первой галереи, первый файл из второй галереи
Users {
galleries: {
created_at: 23.04.2019.
files: [
{
path: "path/to/file.jpg"
},
{
path: "path/to/file3.jpg"
},
]
}
},
Комментарии:
1. Можете ли вы показать, как вы создаете свою коллекцию?
2. Я использую фрактальные преобразователи с
return $this->collection($user->galleries, new GalleryTransformer());
, если вы имеете в виду, что3. Вероятно, лучше посмотреть документацию по пакету. Может быть не чисто Laravel вопрос. Я не могу догадаться, что внутри
GalleryTransformer
🙂
Ответ №1:
Перед передачей данных во фрактальный преобразователь необходимо получить правильные данные. Ваш желаемый результат выглядит как список File
файлов, упорядоченных по Gallery
дате. На самом деле это не имеет никакого отношения к Users
(если вы не планируете позже охватывать возвращаемые данные). При этом красноречивые отношения здесь не помогут, поскольку мы не имеем дело с отношениями одной модели, и мы можем просто использовать конструктор запросов Laravel и использовать groupBy
вспомогательную функцию Collection для организации результатов.
Вам решать, куда поместить этот метод; он может легко перейти в метод контроллера, но если вы планируете ограничить результаты (например, до определенных User
значений или для определенных дат, как показано ниже), вы можете включить его в модель.
// Gallery.php
public static function filesByGalleryDate($date = null) {
$query = DB::table('gallery')
->leftJoin('files', 'galleries.id', '=', 'files.gallery_id')
->select('galleries.created_at', 'files.*')
->orderBy('galleries.created_at');
$result = $date == null
? $query->get()
: $query->where('galleries.created_at', $date)->get();
return $result->groupBy('created_at')
// for each date, convert inner stdClasses to arrays
->map(function($date) {
return $date->map(function($file) {
return (array) $file;
});
});
}