该如何修改关联关系的查询结果??

前言

自己写了一个基于laravel-permission更改的扩展包lumen-permission
根据自己的业务需求,添加了基于route和method判断权限的中间件,支持配置单或多用户角色,支持展示树状结构权限表(递归)

使用

在使用自己的扩展时,使用渴求式查询角色的权限

public function oneWithPermissions(int $roleId)
{
    // 已经定义了角色和权限的关联关系
    $role = $this->one($roleId);
    $role->load('permissions');
    return $role;
}

数据没问题

[
    {
        "id": 1,
        "name": "access.admin",
        "display_name": "权限管理",
        "is_menu": 1,
        "pid": null,
    },
    {
        "id": 2,
        "name": "users.admin",
        "display_name": "用户管理",
        "is_menu": 1,
        "pid": 1,
    }
]

准备通过写好的递归方法将列状转换为树状结构

public function oneWithPermissions(int $roleId)
{
    // 已经定义了角色和权限的关联关系
    $role = $this->one($roleId);
    $role->load('permissions');
    $role->permissions = $role->getPermissionsTree()
    return $role;
}

结果在调试API的时候,出现了这样的数据

[
    {
        "id": 1,
        "name": "access.admin",
        "display_name": "权限管理",
        "is_menu": 1,
        "pid": null,
        "children": [
            {
                "id": 2,
                "name": "users.admin",
                "display_name": "用户管理",
                "is_menu": 1,
                "pid": 1,
                "children": []
            }
        ]
    },
    {
        "id": 2,
        "name": "users.admin",
        "display_name": "用户管理",
        "is_menu": 1,
        "pid": 1,
        "children": []
    }
]

很纳闷,怎么会这样呢,想不明白,就一步一步dd调试
直接返回 $role->permission
或者直接返回 $role->permission->toArray()
没问题啊, 数据都是正常的

[
    {
        "id": 1,
        "name": "access.admin",
        "display_name": "权限管理",
        "is_menu": 1,
        "pid": null,
        "children": [
            {
                "id": 2,
                "name": "users.admin",
                "display_name": "用户管理",
                "is_menu": 1,
                "pid": 1,
                "children": []
            }
        ]
    }
]

于是一步一步跟踪,发现返回到控制器的时候,也是正常了,这就很纳闷了,最后发现 $role->toArray()合并了自身模型的属性和关联关系的属性

namespace Illuminate\Database\Eloquent;

public function toArray()
{
    return array_merge($this->attributesToArray(), $this->relationsToArray());
}

导致 $role->permission = 树状结构(自身新增的模型属性) + 原先的列式结构(关联关系属性)
最后的解决方案是

public function oneWithPermissions(int $roleId)
{
    // 已经定义了角色和权限的关联关系
    $role = $this->one($roleId);
    $permissions = $role->permissions()->get() // 不用$role->permissions也不用$role->load(),会添加关联关系的属性
    $role->permissions = $role->getPermissionsTree(null, $permissions)
    return $role;
}

结语

请教一下大家能有没有更好的解决方案,也欢迎大家star我的扩展包lumen-permission

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 1

顶一下,有没有好的解决方案呀

3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!