Daniel R.
Daniel R.

Reputation: 649

Laravel Eloquent load relationship of the pivot

In my website I have User, Roles and Permissions.

Each user belongs to many Roles (eg. User.php) and pivot table called 'role_user'

public function roles()
{
    return $this->belongsToMany(Role::class);
}

and each Role belongs to many Permissions (eg. Role.php) and pivot table called 'permission_role'

public function permissions()
{
    return $this->belongsToMany(Permission::class);
}

I want to somehow access the User permission but I can't seem to figure it out. Basically I need something like this on the User.php

public function permissions()
{
    return $this->roles()->permissions();
}

Is this possible? Please help. Thank you.

Upvotes: 0

Views: 1105

Answers (2)

Samson Maosa
Samson Maosa

Reputation: 502

If you are using your results in JSON format, this should be very easy if you implement Eloquent Resources

Define three resources as follows:

(Note: to easily define a resource like below, do:

php artisan make:resource UserRes

Then modify the toArray function as you desire. )

UserRes

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class UserRes extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        $user = parent::toArray($request);
        $user["roles"] = RolesRes::collection($this->roles);
        return $user;
    }
}

RolesRes

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class RolesRes extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        $res =  parent::toArray($request);
        $res["permissions"] = $this->permissions;
        return $res;
    }
}

PermissionsRes:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class PermissionsRes extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        $perm = parent::toArray($request);
        return $perm;
    }
}

In my app, here is a screenshot of a sample of results when fetching a single user. Take note of the nesting of multiple roles under which are multiple permissions. Screenshot of a JSON response when querying a single user

Upvotes: 1

Jonas Staudenmeir
Jonas Staudenmeir

Reputation: 25906

Laravel has no native support for a direct relationship.

I created a package for this case: https://github.com/staudenmeir/eloquent-has-many-deep

You can use it like this:

class User extends Model {
    use \Staudenmeir\EloquentHasManyDeep\HasRelationships;

    public function permissions() {
        return $this->hasManyDeep(
            Permission::class, ['role_user', Role::class, 'permission_role']
        );
    }
}

Upvotes: 1

Related Questions