Laravel分页追加属性

时间:2019-04-04 12:31:17

标签: laravel eloquent pagination

我正在将搜索功能从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',
    ]);
});

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

2 个答案:

答案 0 :(得分:1)

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

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

  2. 来自分页器的响应的格式将与来自 $db_query->paginate($num_of_results) 的响应相同(默认情况下,ResourceCollection 将分页元数据移动到响应中的两个子对象,links 和 { {1}},意味着需要重构使用 API 的代码)。

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

meta

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']);
    }
}

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

答案 1 :(得分:0)

我只是通过像这样的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));