首页 > 解决方案 > 从 laravel eloquent 资源集合中隐藏属性关系

问题描述

我正在尝试构建 API 资源,我想在集合中隐藏关系属性。

例如,我只想在 RoleCollection 中隐藏属性“权限”。我的意思是我只想在 Collection 中隐藏这个属性,而不是 Resource。因为 Collection 是从 Resource 调用的,但我不想将它隐藏在 Resource 中。

角色.php

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class Role extends JsonResource
{
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'created_at' => $this->created_at->format('Y-m-d H:i:s'),
            'updated_at' => $this->updated_at->format('Y-m-d H:i:s'),
            'permissions' => Permission::collection($this->permissions),
        ];
    }
}

RoleCollection.php

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\ResourceCollection;

class RoleCollection extends ResourceCollection
{
    public function toArray($request)
    {
        return parent::toArray($request);
    }
}

角色控制器.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use Spatie\Permission\Models\Role;
use App\Http\Resources\Role as RoleResource;
use App\Http\Resources\RoleCollection;

class RoleController extends Controller
{
    public function index()
    {
        $resource = Role::paginate();    
        return new RoleCollection($resource);
    }

    public function show($id)
    {
        $resource = Role::with('permissions')->find($id);    
        return new RoleResource($resource);
    }
}

来自:api/role/1 的响应

{
    "data": {
        "id": 1,
        "name": "Super Administrador",
        "created_at": "2019-05-07 16:45:38",
        "updated_at": "2019-05-07 16:45:38",
        "permissions": [
            {
                "id": 1,
                "name": "user.list"
            },
            {
                "id": 2,
                "name": "user.view"
            },
            {
                "id": 3,
                "name": "user.save"
            },
            {
                "id": 4,
                "name": "user.delete"
            }
        ]
    }
}

来自:/api/roles 的响应

{
    "data": [
        {
            "id": 1,
            "name": "Super Administrador",
            "created_at": "2019-05-07 16:45:38",
            "updated_at": "2019-05-07 16:45:38",
            "permissions": [
                {
                    "id": 1,
                    "name": "user.list"
                },
                {
                    "id": 2,
                    "name": "user.view"
                },
                {
                    "id": 3,
                    "name": "user.save"
                },
                {
                    "id": 4,
                    "name": "user.delete"
                }
            ]
        },
        {
            "id": 2,
            "name": "Administrador",
            "created_at": "2019-05-07 16:45:38",
            "updated_at": "2019-05-07 16:45:38",
            "permissions": []
        }
    ],
    "links": {
        "first": "http://127.0.0.1:32773/api/roles?page=1",
        "last": "http://127.0.0.1:32773/api/roles?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "path": "http://127.0.0.1:32773/api/roles",
        "per_page": 15,
        "to": 2,
        "total": 2
    }
}

标签: phplaraveleloquent

解决方案


一种方法是使用该whenLoaded方法。当关系尚未加载时,whenLoaded将返回一个实例。MissingValueLaravel 反过来会将此属性排除在您的共鸣之外。

它不仅有助于隐藏某些响应中的属性,而且有助于提高性能。当前,您的资源将在每次未加载此关系时执行查询以获取Permission模型。Role

您的资源可能如下所示:

return [
    ...
    'permissions' => Permission::collection($this->whenLoaded('permissions')),
];

Laravel 文档


推荐阅读