如何使用 Laravel API 资源对加载的关系进行分页
Posted
技术标签:
【中文标题】如何使用 Laravel API 资源对加载的关系进行分页【英文标题】:How to Paginate loaded relation with Laravel API resources 【发布时间】:2019-11-30 18:00:59 【问题描述】:我需要在它的资源中加载模型关系并对其进行分页。
就我而言,我有 Category
和 Path
模型,以及 CategoryResource
和 PathResource
CategoryResource
的toArray
方法如下:
public function toArray($request)
return [
'id' => $this->id,
'name' => $this->name,
'slug' => $this->slug,
'order' => $this->order,
'paths' => PathResource::collection($this->whenLoaded('paths'))
];
PathResource
的toArray
方法如下:
public function toArray($request)
return parent::toArray($request);
问题是如何在我的CategoryResource
中加载和分页相关的Path
?
【问题讨论】:
您找到解决问题的方法了吗?我也对同样的问题感到震惊,找不到答案 @LizeshShakya 我发布了这个问题的答案。 【参考方案1】:我遇到了同样的问题并通过这种方式解决了:
先决条件
您必须拥有/创建Path
模型的资源,即PathResource
创建一个使用这个命令:
php artisan make:resource PathResource
解决方案
解决方案是在关系上使用 laravel paginate
并在分页集合上使用 transform
方法将其项目转换为您的资源。
第一步
使用以下命令创建一个基类,用于对应用中的任何资源进行分页:
php artisan make:resource PaginatedCollection -c
编辑PaginatedCollection
并添加以下代码:
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\ResourceCollection;
class PaginatedCollection extends ResourceCollection
/**
* An array to store pagination data that comes from paginate() method.
* @var array
*/
protected $pagination;
/**
* PaginatedCollection constructor.
*
* @param mixed $resource paginated resource using paginate method on models or relations.
*/
public function __construct($resource)
$this->pagination = [
'total' => $resource->total(), // all models count
'count' => $resource->count(), // paginated result count
'per_page' => $resource->perPage(),
'current_page' => $resource->currentPage(),
'total_pages' => $resource->lastPage()
];
$resource = $resource->getCollection();
parent::__construct($resource);
/**
* Transform the resource collection into an array.
* now we have data and pagination info.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
return [
// our resources
'data' => $this->collection,
// pagination data
'pagination' => $this->pagination
];
第二步
为您的模型创建一个集合资源并扩展PaginatedCollection
而不是默认的ResourceCollection
。
运行以下命令:php artisan make:resource PathCollection -c
现在编辑您的新集合类 PathCollection
并覆盖 toArray
方法:
/**
* Transform the resource collection into an array.
*
* In this method use your already created resources
* to avoid code duplications
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
return [
// Here we transform any item in paginated items to a resource
'data' => $this->collection->transform(function ($path)
return new PathResource($path);
),
'pagination' => $this->pagination,
];
最后一步
在您的CategoryResource
中使用PathCollection
,如下所示:
return [
'id' => $this->id,
'name' => $this->name,
'slug' => $this->slug,
'order' => $this->order,
'paths' => new PathCollection(
new LengthAwarePaginator(
$this->whenLoaded('paths'),
$this->paths_count,
10
)
),
];
并确保导入 LengthAwarePaginator
类:use Illuminate\Pagination\LengthAwarePaginator;
用法
$category = Category::with('paths')->withCount('paths')->find(1);
return new CategoryResource($category);
【讨论】:
【参考方案2】:您可能应该查看有关 Resources 和 ResourceCollections 的文档。 ResourceCollections 将允许您轻松地对资源进行分页。 Api Resource Collection Pagination Documentation
【讨论】:
该文档仅显示了如何对整个模型进行分页。问题是如何在 toArray 方法中对资源内部模型的关系进行分页?以上是关于如何使用 Laravel API 资源对加载的关系进行分页的主要内容,如果未能解决你的问题,请参考以下文章