РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
514 of 1392 menu

Класс ResourceCollection

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

При создании ресурса для коллекции необходимо определить метод toArray, который принимает текущий запрос и возвращает массив данных. В отличие от JsonResource, где метод работает с одной моделью, ResourceCollection работает с коллекцией и предоставляет доступ к методам пагинации через свойство resource, если передана пагинированная коллекция.

Синтаксис

<?php namespace AppHttpResources; use IlluminateHttpResourcesJsonResourceCollection; class UserCollection extends ResourceCollection { public function toArray($request) { return [ 'data' => $this->collection, 'meta' => [ 'total' => $this->total(), 'count' => $this->count(), ], ]; } } ?>

Создание ресурса коллекции

Для создания ресурса коллекции используется Artisan-команда make:resource с флагом --collection. Это сгенерирует класс, наследующий от ResourceCollection:

php artisan make:resource UserCollection --collection

Сгенерированный класс будет расположен в директории app/Http/Resources. Рассмотрим базовую структуру такого класса:

<?php namespace AppHttpResources; use IlluminateHttpResourcesJsonResourceCollection; class UserCollection extends ResourceCollection { public function toArray($request) { return [ 'data' => $this->collection, ]; } } ?>

Пример с отдельным ресурсом

Создадим ресурс для модели пользователя, который будет использоваться внутри коллекции:

<?php namespace AppHttpResources; use IlluminateHttpResourcesJsonJsonResource; class UserResource extends JsonResource { public function toArray($request) { return [ 'id' => $this->id, 'name' => $this->name, 'email' => $this->email, 'created_at' => $this->created_at, ]; } } ?>

Теперь создадим коллекцию, которая будет использовать этот ресурс:

<?php namespace AppHttpResources; use IlluminateHttpResourcesJsonResourceCollection; class UserCollection extends ResourceCollection { public $collects = UserResource::class; public function toArray($request) { return [ 'data' => $this->collection, 'count' => $this->collection->count(), ]; } } ?>

Используем коллекцию в контроллере:

<?php namespace AppHttpControllers; use AppModelsUser; use AppHttpResourcesUserCollection; class UserController extends Controller { public function index() { $users = User::all(); return new UserCollection($users); } } ?>

Результат выполнения кода:

{ "data": [ { "id": 1, "name": "John Doe", "email": "john@example.com", "created_at": "2024-01-01 12:00:00" }, { "id": 2, "name": "Jane Smith", "email": "jane@example.com", "created_at": "2024-01-02 12:00:00" } ], "count": 2 }

Работа с пагинацией

ResourceCollection автоматически определяет, является ли переданная коллекция пагинированной, и предоставляет доступ к методам пагинации:

<?php namespace AppHttpResources; use IlluminateHttpResourcesJsonResourceCollection; class PostCollection extends ResourceCollection { public function toArray($request) { return [ 'data' => $this->collection, 'pagination' => [ 'total' => $this->total(), 'per_page' => $this->perPage(), 'current_page' => $this->currentPage(), 'last_page' => $this->lastPage(), ], ]; } } ?>

Использование в контроллере с пагинацией:

<?php namespace AppHttpControllers; use AppModelsPost; use AppHttpResourcesPostCollection; class PostController extends Controller { public function index() { $posts = Post::paginate(10); return new PostCollection($posts); } } ?>

Результат выполнения кода:

{ "data": [ { "id": 1, "title": "First Post", "content": "Content of first post" }, { "id": 2, "title": "Second Post", "content": "Content of second post" } ], "pagination": { "total": 25, "per_page": 10, "current_page": 1, "last_page": 3 } }

Добавление метаданных

Для добавления метаданных к ответу используется метод with. Это позволяет включать дополнительную информацию, которая не относится непосредственно к данным:

<?php namespace AppHttpResources; use IlluminateHttpResourcesJsonResourceCollection; class ProductCollection extends ResourceCollection { public function toArray($request) { return [ 'data' => $this->collection, ]; } public function with($request) { return [ 'meta' => [ 'timestamp' => now(), 'version' => '1.0.0', 'total_products' => $this->collection->count(), ], ]; } } ?>

Условная фильтрация данных

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

<?php namespace AppHttpResources; use IlluminateHttpResourcesJsonJsonResource; class AdminUserResource extends JsonResource { public function toArray($request) { return [ 'id' => $this->id, 'name' => $this->name, 'email' => $this->email, 'admin_notes' => $this->when( $request->user()->isAdmin(), $this->admin_notes ), ]; } } ?>

Преобразование без отдельного ресурса

Если не требуется создавать отдельный ресурс для каждого элемента, можно использовать collect для преобразования коллекции непосредственно внутри метода:

<?php namespace AppHttpResources; use IlluminateHttpResourcesJsonResourceCollection; class SimpleCollection extends ResourceCollection { public function toArray($request) { return $this->collection->map(function ($item) { return [ 'id' => $item->id, 'title' => $item->title, 'short_description' => substr($item->description, 0, 50), ]; }); } } ?>

Использование в контроллере:

<?php namespace AppHttpControllers; use AppModelsArticle; use AppHttpResourcesSimpleCollection; class ArticleController extends Controller { public function index() { $articles = Article::latest()->take(5)->get(); return new SimpleCollection($articles); } } ?>

Результат выполнения кода:

[ { "id": 1, "title": "Article 1", "short_description": "Description of article 1" }, { "id": 2, "title": "Article 2", "short_description": "Description of article 2" } ]

Смотрите также

  • класс JsonResource,
    который используется для преобразования отдельных моделей
  • метод toArray,
    который определяет структуру данных ресурса
  • метод with,
    который добавляет метаданные к ответу
  • метод wrap,
    который управляет оберткой данных ресурса
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить