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
相关产品推荐
相关产品推荐

