【问题标题】:Laravel paginate append attributesLaravel 分页追加属性
【发布时间】:2019-08-26 05:11:28
【问题描述】:

我正在将我的搜索功能从 php 重建为 vue。

在 php 中,我曾经为我的模型类添加属性,例如 html 标签、缩略图等。 我可以用$model->HtmlThumb 抓住它,然后属性就会被加载。 现在,由于我收到了 json 响应,因此标签不存在。 我知道我可以简单地在模型类上使用$appends 属性。

问题是属性总是被附加,这是我绝对不想要的。

我知道我可以使用 hideAttributes 或类似的东西手动隐藏这些属性,但在现有应用程序中这样做并不方便。

这样它应该可以工作,但现在它返回一个项目数组而不是分页器集合。

$results = $db_query->paginate($num_of_results)->appends($result)->each(function($project){
    $result->setAppends([
        'ProjectDescription',
        'FileCountLabel',
    ]);
});

我正在寻找一种正确执行此操作的方法。

【问题讨论】:

标签: laravel eloquent pagination


【解决方案1】:

我刚刚用这样的 ResourceCollection 修复了它:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\ResourceCollection;

class ProjectCollection extends ResourceCollection
{
    /**
     * Transform the resource collection into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        // return parent::toArray($request);

        return [
          'data' => $this->collection->each(function($model){
            $model->setAppends([
                'ProjectDescription',
                'FileCountLabel',
            ]);
          }),
        ];
    }
}
$results = new ProjectCollection($db_query->paginate($num_of_results)->appends($appends));

【讨论】:

  • 您应该使用append() 而不是setAppends(),因为显然setAppends() 将取消设置/删除模型文件的$appends 属性中设置的所有其他属性,传递的属性名称数组除外在 Laravel v8.x 上。
【解决方案2】:

OP 接受的答案是正确且有效的,但我想提出一个具有两个优点的替代答案:

  1. 它不必为每个模型类型和附加属性的每个组合创建一个新的 ResourceCollection。

  2. 来自分页器的响应将采用与来自$db_query-&gt;paginate($num_of_results) 的响应相同的格式(ResourceCollection 默认将分页元数据移动到响应中的两个子对象linksmeta,这意味着代码使用 API 需要重构)。

我们的想法是创建一个通用的 ResourceCollection,它允许我们动态控制附加的属性:

app/Resources/AppendablePaginator.php

<?php

namespace App\Http\Resources;

use Illuminate\Support\Arr;
use Illuminate\Http\Resources\Json\PaginatedResourceResponse;
use Illuminate\Http\Resources\Json\ResourceCollection;
use Illuminate\Pagination\AbstractPaginator;

class AppendablePaginator extends ResourceCollection
{
    private $appends = [];

    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'data' => $this->collection->each->append($this->appends)
        ];
    }

    /**
     * Create an HTTP response that represents the object.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function toResponse($request)
    {
        return $this->resource instanceof AbstractPaginator
                    ? (new FlattenedPaginatedResourceResponse($this))->toResponse($request)
                    : parent::toResponse($request);
    }

    /**
     * Append to the underlying models
     * @param  array|string|null  $key
     */
    public function modelAppend($key) {
        if (is_null($key)) {
            return $this;
        }

        if (is_array($key)) {
            $this->appends = array_merge($this->appends, $key);
        } else {
            $this->appends[] = $key;
        }
        
        return $this;
    }
}

class FlattenedPaginatedResourceResponse extends PaginatedResourceResponse {
    /**
     * Add the pagination information to the response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    protected function paginationInformation($request)
    {
        $paginated = $this->resource->resource->toArray();
        return Arr::except($paginated, ['data']);
    }
}

现在我们可以动态追加:

$results = (new AppendablePaginator($db_query->paginate($num_of_results))->modelAppend([
    'ProjectDescription',
    'FileCountLabel'
]);

这意味着我们可以轻松更改附加属性,并且由于此代码适用于任何模型类型,我们不必担心生成新集合。

【讨论】:

    猜你喜欢
    • 2018-01-17
    • 1970-01-01
    • 2019-04-29
    • 2020-03-22
    • 1970-01-01
    • 2011-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多