I have a problem when returning an api resource. I am using Spatie Laravel Permission.
It happens that in my particular case I am trying to return an api resource with the details of the user and next to them the roles and permissions that the user has.
My UserResorce.php
class UserResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param Request $request
* @return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'roles' => RoleResource::collection($this->whenLoaded('roles')),
'permissions' => PermissionResource::collection($this->whenLoaded('permissions')),
];
}
}
My RoleResource.php
class RoleResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param Request $request
* @return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'permissions' => PermissionResource::collection($this->whenLoaded('permissions'))
];
}
}
My PermissionResource.php
class PermissionResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param Request $request
* @return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name
];
}
}
As you can see in the UserResource.php
file, I only load the roles
and permissions
when they are really needed. In this way if I do the following:
class UserController extends Controller
{
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
return UserResource::make(User::find(1));
}
I get the following result:
{
"data": {
"id":1,
"name":"User Name 1",
"email":"admin@example.com",
}
}
So to load the same result but this time with the roles associated with the user I do the following:
class UserController extends Controller
{
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
return UserResource::make(User::with(['roles'])->find(1));
}
and as expected I get the following result:
{
"data": {
"id":1,
"name":"User Name 1",
"email":"admin@example.com",
"roles": {
0: {
"id": 1,
"name": "Administrator",
}
}
}
}
Now my problem is the following, to get the user roles and permissions I did the following:
class UserController extends Controller
{
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
return UserResource::make(User::with(['roles', 'permissions'])->find(1));
}
but I get an empty object in the "permissions"
key, so I analyzed more carefully and it is that the permissions that user has are defined by their role
, I looked in the documentation and I saw that I can obtain all the permissions of a user using getAllPermissions()
method. So I did the following:
class UserResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param Request $request
* @return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'roles' => RoleResource::collection($this->whenLoaded('roles')),
'permissions' => PermissionResource::collection($this->whenLoaded('permissions', function () {
return $this->getAllPermissions();
})),
];
}
}
but in this way, it also loads the permissions
in the roles relation and it would obtain an unexpected result like the following:
{
"data": {
"id":1,
"name":"User Name 1",
"email":"admin@example.com",
"roles": {
0: {
"id": 1,
"name": "Administrator",
"permissions": {
0: {
"id": 1
"name": "Create Users"
}
}
}
},
"permissions": {
0: {
"id": 1,
"name": "Create Users",
}
}
}
and it is not the expected result, since the result that I expect when executing:
return UserResource::make(User::with(['roles', 'permissions'])->find(1));
should by the following:
{
"data": {
"id":1,
"name":"User Name 1",
"email":"admin@example.com",
"roles": {
0: {
"id": 1,
"name": "Administrator",
}
},
"permissions": {
0: {
"id": 1,
"name": "Create Users",
}
}
}
and when execute:
return UserResource::make(User::with(['roles.permissions', 'permissions'])->find(1));
I expect the following result:
{
"data": {
"id":1,
"name":"User Name 1",
"email":"admin@example.com",
"roles": {
0: {
"id": 1,
"name": "Administrator",
"permissions": {
0: {
"id": 1
"name": "Create Users"
}
}
}
},
"permissions": {
0: {
"id": 1,
"name": "Create Users",
}
}
}
Could someone help me with this problem? Thank you very much in advance.