【问题标题】:How to sort Laravels API-Resource如何对 Laravel API 资源进行排序
【发布时间】:2019-09-24 16:02:40
【问题描述】:

我正在从我的应用程序的 api-backend 检索车辆列表,使用 VueJS 和 Axios 在前端,Laravels API-Resources 在后端。我在 Vehicle-model 上使用本地动态范围来完成过滤。这一切都很好。

现在我想在将结果发送到客户端之前对其进行排序。在将结果传递给 VehicleCollectionResource 之前对其进行排序会导致错误,即我的 VehicleResourceCollection 中没有几个函数(例如 $this->total()$this->count())。

将查询结果传递给结果,如下所示,ResourceCollection 接收到一个有效的分页集合(未排序)。尝试对 CollectionResource 中的集合进行排序只会对整个集合的一小部分(一个“页面”)进行排序。

我无法直接在数据库上进行排序,因为某些排序参数需要额外的计算或来自其他模型的信息。

那么我如何从我的数据库中查询条目,对它们进行排序,然后对它们进行分页以便下一个?我必须实现自己的分页逻辑吗?

VehicleCollectionResource 中的我的 toArray 函数:

public function toArray($request)
{
    $sortParameters = $this->sortParameters;
    $collection = $this->collection->sortBy(function ($vehicle) use ($sortParameters) {
        return $this->getSortingAttribute($vehicle, $sortParameters);
    })->toArray();

    return [
        'data' => $collection,
        'links' => [
            'self' => 'link-value'
        ],
        'pagination' => [
            'total' => $this->total(),
            'count' => $this->count(),
            'per_page' => 5,
            'current_page' => $this->currentPage(),
            'total_pages' => $this->lastPage()
        ]
    ];
}

我的 ApiVehicleController(接收请求):

public function filter(Request $request)
{
    $query = Vehicle::available();

    // chain scopes to the query
    if ($request->has('producer') && $request->get('producer') !== null) {
        $query = $query->producer([$request->get('producer')]);
    }

    // other scopes ...

    $sortParameters = [
        'sortAfter' => $request->get('sort') ?? 'priceAsc',
        'mileage' => Mileage::where('id', $request->get('mileage'))->first() ?? NULL,
        'months' => Month::where('id', $request->get('duration'))->first() ?? NULL,
        'location' => $request->get('location')
    ];

    // Pass result to the CollectionResource
    return new VehicleCollectionResource($query->paginate(5), $sortParameters);
}

开始排序

【问题讨论】:

  • 您应该在分页前对查询进行orderBy
  • 这个 ordsrBy 是在查询期间执行还是在查询返回的集合上执行?正如我所说,我有复杂的排序参数,无法在数据库上执行。

标签: php laravel sorting


【解决方案1】:

事实是:

  • 分页后不能排序,因为此时你只有一页数据,而不是整个集合

  • 在执行查询之前,不能使用count()total()等函数。

因此,只有两种有效的可能性:

  1. 您使用orderBy() 并在SQL 查询中对您的集合进行排序(甚至使用DB::raw() 来构建复杂的条件)。 SQL 非常高效,几乎所有事情都可以使用它完成,但构建正确的查询可能并非易事。
  2. 如果不能使用 SQL orderBy,则不能使用 paginate() 实用程序。您无需使用它,而是获得整个集合 ($query->get()),对其进行排序,然后手动对其进行分页。一个有用的集合方法是forPage

【讨论】:

    猜你喜欢
    • 2019-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    • 2021-11-18
    • 1970-01-01
    • 2019-11-30
    • 2017-11-20
    相关资源
    最近更新 更多