Laravel 9中用Spatie权限包,如何将Role的Permissions转为数组?
解决Laravel Spatie权限包中Role关联Permissions返回字符串数组的问题
原代码问题分析
你之前尝试的查询写法有误:pluck()是集合方法,不能直接在关联查询的闭包中使用,闭包仅支持查询构造器的方法(如select),所以无法达到预期效果。
下面提供三种可行的实现方案,按需选择:
方案一:控制器内直接处理结果(快速实现)
在获取Role实例后,手动将权限集合转换为名称数组:
/** * Display the specified resource. * * @param int $id * @return \Illuminate\Http\Response */ public function show($id) { $this->authorize('view', Role::class); $role = Role::with('permissions')->find($id); if (!$role) { return new ApiSuccessResponse(null, [ 'message' => 'Role not found or invalid role ID.' ], 404); } // 将权限对象集合转换为名称字符串数组 $role->permissions = $role->permissions->pluck('name')->toArray(); return new ApiSuccessResponse($role); }
方案二:模型访问器(优雅持久化处理)
在Role模型中定义访问器,统一处理权限字段的返回格式,避免重复代码:
use Illuminate\Database\Eloquent\Casts\Attribute; class Role extends \Spatie\Permission\Models\Role { // 隐藏原有的permissions关联对象,避免返回冗余数据 protected $hidden = ['permissions']; // 定义访问器,返回权限名称数组 protected function permissions(): Attribute { return Attribute::make( get: fn () => $this->permissions()->pluck('name')->toArray(), ); } }
注意:如果不想覆盖原
permissions属性,可以将访问器命名为permissionNames,并添加到模型的$appends数组中,前端通过permission_names字段获取数组。
方案三:API资源类(适合复杂API场景)
创建Role资源类,统一规范API返回结构,便于后续维护:
- 生成资源类:
php artisan make:resource RoleResource
- 修改
RoleResource的toArray方法:
namespace App\Http\Resources; use Illuminate\Http\Request; use Illuminate\Http\Resources\Json\JsonResource; class RoleResource extends JsonResource { /** * Transform the resource into an array. * * @return array<string, mixed> */ public function toArray(Request $request): array { return [ 'id' => $this->id, 'company_id' => $this->company_id, 'name' => $this->name, 'guard_name' => $this->guard_name, 'created_at' => $this->created_at, 'updated_at' => $this->updated_at, 'permissions' => $this->permissions->pluck('name')->toArray(), ]; } }
- 在控制器中返回资源:
public function show($id) { $this->authorize('view', Role::class); $role = Role::with('permissions')->find($id); if (!$role) { return new ApiSuccessResponse(null, [ 'message' => 'Role not found or invalid role ID.' ], 404); } return new ApiSuccessResponse(new RoleResource($role)); }
内容的提问来源于stack exchange,提问作者Ryan H
相关产品推荐
相关产品推荐

