简体   繁体   English

在Laravel资源集合中过滤属性

[英]Filter attributes in Laravel Resource Collection

In the new Laravel Resource classes, you are able to remove attributes based on anything you like. 在新的Laravel Resource类中,您可以根据自己喜欢的任何内容删除属性。

If you want to return many items, you can use the function 如果要返回许多项目,可以使用该功能

Resource::collection()

But that does not let you add metadata in one place. 但这不允许您在一个地方添加元数据。 Enter a Collection, great, this is many items in a nice format with the ability to add meta data. 输入一个集合,很棒,这是一个很好的格式的项目,能够添加元数据。 What you cannot do though, is filter the collection you have to hide attributes like you can with a resource. 但你不能做的是过滤你必须隐藏属性的集合,就像你可以用资源一样。 The only way I can see to do it is 我能看到的唯一方法是

foreach ($this->collection as $item) {
        if ($notAdmin) {
            $temp = array_except($item->toArray(), ['secret']);
        }
        $temp['links'] = ['self' => route('restaurant.show', [$item])];
        $data[] = $temp;
    }

Is there something I am missing? 有什么我想念的吗? This seems like a massive overlooked ability for a Resource Collection 这似乎是资源收集的一个巨大的被忽视的能力

Based in this thread, it seems that when using a ResourceCollection class to customize a collection (for example BookCollection ) Laravel look up for a Resource class named the same but without the Collection sufix class (in the example, a class named just Book ). 基于线程,似乎在使用ResourceCollection类来自定义集合时(例如BookCollection ),Laravel会查找名为相同但没有Collection sufix类的Resource类(在示例中,名为Just Book的类)。

So you will need to have a resource class named: Book where you customize the attributes to be returned to the response and a collection class named: BookCollection , that will use Book -to customize the data- and will also let you customize the metadata. 因此,您需要有一个名为的BookBook ,您可以自定义要返回到响应的属性,以及一个名为BookCollection的集合类,它将使用Book定义数据,并且还可以自定义元数据。

app/Http/Resources/Book.php 应用程序/ HTTP /资源/ book.php中

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\Resource;

class Book extends Resource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'title' => $this->title,
        ];
    }
}

app/Http/Resources/BookCollection.php 应用程序/ HTTP /资源/ BookCollection.php

<?php

namespace App\Http\Resources\Users;

use Illuminate\Http\Resources\Json\ResourceCollection;

class BookCollection extends ResourceCollection
{
    /**
     * Transform the resource collection into an array.
     *
     * @param  \Illuminate\Http\Request
     * @return array
     */
    public function toArray($request)
    {
        return $this->collection;
    }

    public function with($request)    
    {
        return [
            'meta' => [
                'key' => 'value',
            ],
        ];
    }
}

Ok, here's how you do it: 好的,这是你如何做到的:

  1. Create a Resource for a single resource, where you can easily have conditional attributes 创建Resource对于单个资源,在这里你可以轻松拥有条件属性

  2. Create a RCollection for the collection, where you can add meta data . 为集合创建RCollection ,您可以在其中添加元数据

  3. Pass the Resource::collection(Model::all) into the new RCollection() . Resource::collection(Model::all)传递给new RCollection()

Something like this (from my testing): 像这样的东西(来自我的测试):

Route::get('users/all', function() {
    return new \App\Http\Resources\Users(
        \App\Http\Resources\UserResource::collection(\App\User::get())
    );
});

Works like a charm! 奇迹般有效!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM