You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Spatie Permissions:仅获取用户关联角色的id和name

解决Laravel Spatie Permissions返回精简角色字段的问题

嘿,我之前在项目里用Spatie权限的时候也碰到过这个需求,其实不用修改模型的关联关系,在UserResource里就能轻松搞定,给你几个实用的方案:

方案一:直接在UserResource中映射角色字段

这是最直接的方式,通过集合的map方法遍历角色,只提取你需要的id和name:

class UserResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param \Illuminate\Http\Request $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'surname' => $this->surname,
            'email' => $this->email,
            'inactive' => $this->inactive,
            'roles' => $this->roles->map(function ($role) {
                return [
                    'id' => $role->id,
                    'name' => $role->name,
                ];
            })
        ];
    }
}

这个方法不需要额外创建文件,快速就能实现需求。

方案二:创建RoleResource(推荐)

如果你的项目里其他地方也需要返回精简的角色数据,创建一个专门的RoleResource会更符合Laravel的资源设计规范,还能复用代码:

首先生成RoleResource:

php artisan make:resource RoleResource

然后修改RoleResource的内容:

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

最后在UserResource里调用这个资源集合:

use App\Http\Resources\RoleResource;

class UserResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'surname' => $this->surname,
            'email' => $this->email,
            'inactive' => $this->inactive,
            'roles' => RoleResource::collection($this->roles)
        ];
    }
}

这种方式更优雅,后续如果要调整角色返回的字段,只需要修改RoleResource一处即可。

方案三:优化查询,减少不必要字段加载(可选)

如果想从数据库查询阶段就只获取需要的字段,提升性能,可以在加载角色关联的时候指定字段:

方式1:修改User模型的roles关联

use Spatie\Permission\Models\Role;

class User extends Authenticatable
{
    // ...其他代码
    public function roles()
    {
        return $this->belongsToMany(Role::class)->select(['roles.id', 'roles.name']);
    }
}

方式2:查询用户时指定关联字段

在查询用户列表的时候,用with方法指定要加载的角色字段:

$users = User::with('roles:id,name')->get();

这样数据库只会查询角色的id和name字段,减少数据传输量,配合上面的资源方案使用效果更好。

内容的提问来源于stack exchange,提问作者Guido Caffa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 20:47:41