【问题标题】:How to remove some values in collection when using Laravel API Resource使用 Laravel API 资源时如何删除集合中的某些值
【发布时间】:2020-03-30 16:52:37
【问题描述】:

我在一个博客项目中。我的 Post 模型有这个 API 资源

return [
    'id' => $this->id,
    'title' => $this->title,
    'body' => $this->body,
    'date' => $this->date
];

但是当我收集帖子时我不想得到'body' => $this->body,因为我只在我想显示帖子时使用它,而不是列出它们

我该怎么做?我应该使用资源集合吗?

更新: makeHidden 应该可以工作,但不是因为我们有Illuminate\Support\Collection 而不是Illuminate\Database\Eloquent\Collection,我怎样才能进行强制转换或使API 资源的收集方法返回Illuminate\Database\Eloquent\Collection 实例?

【问题讨论】:

    标签: laravel eloquent laravel-6 laravel-eloquent-resource laravel-api


    【解决方案1】:

    我假设你有一个PostResource,如果你没有,你可以生成一个:

    php artisan make:resource PostResource
    

    覆盖PostResource 上的收集方法并过滤字段:

    class PostResource extends Resource
    {
        protected $withoutFields = [];
    
        public static function collection($resource)
        {
            return tap(new PostResourceCollection($resource), function ($collection) {
                $collection->collects = __CLASS__;
            });
        }
    
        // Set the keys that are supposed to be filtered out
        public function hide(array $fields)
        {
            $this->withoutFields = $fields;
            return $this;
        }
    
        // Remove the filtered keys.
        protected function filterFields($array)
        {
            return collect($array)->forget($this->withoutFields)->toArray();
        }
    
        public function toArray($request)
        {
            return $this->filterFields([
                'id' => $this->id,
                'title' => $this->title,
                'body' => $this->body,
                'date' => $this->date
            ]);
        }
    }
    

    你需要创建一个PostResourceCollection

    php artisan make:resource --collection PostResourceCollection 
    

    这里正在使用隐藏字段处理集合

    class PostResourceCollection extends ResourceCollection
    {
        protected $withoutFields = [];
    
        // Transform the resource collection into an array.
        public function toArray($request)
        {
            return $this->processCollection($request);
        }
    
        public function hide(array $fields)
        {
            $this->withoutFields = $fields;
            return $this;
        }
        // Send fields to hide to UsersResource while processing the collection.
        protected function processCollection($request)
        {
            return $this->collection->map(function (PostResource $resource) use ($request) {
                return $resource->hide($this->withoutFields)->toArray($request);
            })->all();
        }
    }
    

    现在在PostController 中,您可以调用hide 方法并隐藏要隐藏的字段:

    public function index()
    {
        $posts = Post::all();
        return PostResource::collection($posts)->hide(['body']);
    }
    

    你应该得到一个没有正文字段的帖子集合。

    【讨论】:

    • 它不起作用,“方法 Illuminate\Support\Collection::hide 不存在。”
    【解决方案2】:

    有一个方法可以有条件地向资源添加属性,如下所示

    return [
        'attribute' => $this->when(Auth::user()->isAdmin(), 'attribute-value'),
    ];
    

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 2020-01-05
      • 2020-06-25
      • 2023-03-12
      • 2020-07-04
      • 1970-01-01
      • 1970-01-01
      • 2019-10-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多