Ресурс API Laravel. Группировка и сведения из одной таблицы

Я пытаюсь изучить API Laravel и ломаю голову над тем, что должно быть простой проблемой. У меня есть одна таблица базы данных с данными о продажах, возвращающая эту коллекцию ресурсов API.

{
    "id": "1",
    "itemCode": "item1",
    "date": "2024-06-10",
    "qty": "1"
},
{
    "id": "2",
    "itemCode": "item1",
    "date": "2024-06-10",
    "qty": "10"
},
{
    "id": "3",
    "itemCode": "item1",
    "date": "2024-06-08",
    "qty": "5"
},
{
    "id": "4",
    "itemCode": "item2",
    "date": "2024-06-10",
    "qty": "2"
}

Я пытаюсь сгруппировать их по itemCode и дате, но сохраняю все данные в столбце подуровня «подробности».

Я пытаюсь достичь этого результата:

{
    "itemCode": "item1",
    "date": "2024-06-10",
    "details": 
    [
        {"id": "1", "qty": "1"},
        {"id": "2", "qty": "10"},
    ]
},
{
    "itemCode": "item1",
    "date": "2024-06-08",
    "details": 
    [
        {"id": "3", "qty": "5"},
    ]
},
{
    "itemCode": "item2",
    "date": "2024-06-08",
    "details": 
    [
        {"id": "4", "qty": "2"},
    ]
}

Мне удалось достичь ожидаемых результатов с первого раза в моем контроллере

 $summary = orders::select('id','date', 'itemCode', 'qty')
            ->groupBy('id','date', 'itemCode', 'qty')

return orderGroupResource::collection($summary);

И на моем ресурсе:

return [
    'date' => $this->date,
    'itemCode' => $this->itemCode,
    'details' =>
    detailResource::collection(order::where('date', $this->date)
        ->where('itemCode', $this->itemCode)
        ->get()),
];

Однако в результате для каждой группы создается один новый запрос, и кажется, что его можно решить более эффективным способом.

что означают детали, у вас есть таблица order_items? или как узнать подробности

Umer Fayyaz 13.06.2024 16:00

Подробности – это исходные нефильтрованные данные. Из этих данных я пытаюсь получить ключ верхнего уровня для каждого элемента и дня. Поэтому, когда интерфейс выполняет итерацию возвращенного массива, он сначала получает каждый элемент и день, а затем все заказы в массиве подуровней.

Johan 14.06.2024 08:11
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
2
72
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Есть несколько способов сделать это. Поскольку вы используете ресурсы, вы можете поиграть с этим

ПодробноРесурс

public function toArray($request)
{
    return [
        'id' => $this->id,
        'qty' => $this->qty,
    ];
}

В ресурсе группы заказов

$grouped = $this->resource->groupBy(function ($item) {
    return $item['itemCode'] . '-' . $item['date'];
}); # expined down

return $grouped->map(function ($group) {
    $first = $group->first();
    return [
        'itemCode' => $first->itemCode,
        'date' => $first->date,
        'details' => DetailResource::collection($group->values()),
    ];
})->values();

Группировка элементов по itemCode и date для создания уникального ключа, позволяющего методу groupBy эффективно группировать элементы.

В контроллере

public function getSummary()
{
    $orders = Order::all();
    return new OrderGroupResource($orders);
}

Это похоже на то, чего я пытаюсь достичь, но получаю ошибку: «Вызов неопределенного метода Illuminate\Database\Eloquent\Builder::map()»

Johan 14.06.2024 08:08

@Йохан, ты добавил это $orders = Order::all(); return new OrderGroupResource($orders); В контроллере

Abdulla Nilam 14.06.2024 09:07

и убедитесь, что $orders не пуст

Abdulla Nilam 14.06.2024 09:08

Конечно, я перенастраивал коллекцию OrderGroupResource. Также мне нужно было добавить ->toArray() после ->values() в OrderGroupResource. Большое спасибо за вашу помощь!

Johan 14.06.2024 09:51

Другие вопросы по теме