简体   繁体   中英

Laravel Eloquent: How get the 3rd model using first model that only connects by the 2nd model

I have User, Role and Permission model. User's have relation only with role and role to permission only, so Users and permissions have no connection between.

Role model

public function users(){
   return $this->belongsToMany('App\User', 'role_user', 'user_id', 'role_id');
}

public function permissions(){
    return $this->belongsToMany('App\Permission', 'permission_role', 'permission_id', 'role_id');
}

User model

public function roles(){
   return $this->belongsToMany('App\Role', 'role_user', 'user_id', 'role_id');
}

Permission model

public function roles(){
    return $this->belongsToMany('App\Role', 'permission_role', 'permission_id', 'role_id');
}

So I'm able to get the users role if I do

$users->roles

Now how can I get the users role permissions directly using my User model which connected only with roles and roles that only one who connects with permission

$users->role()->permission

If you are looking to just display the permissions on the user's profile, for example, a nested foreach will do the trick:

<p class="strong">Roles:</p>
    <ul class="list-group">
        @foreach ($user->roles as $role)
            <li class="list-unstyled">{{ Html::link(url('/roles/'.$role->id),$role->label) }}</li>
            <ul class="list-group">
                @foreach ($role->permissions as $permission)
                    <li class="list-unstyled">{{ Html::link(url('/permissions/'.$permission->id),$permission->label) }}</li>
                @endforeach
            </ul>
        @endforeach
    </ul>

Laravel provides a hasManyThrough method which is exactly what you need. The "has-many-through" relationship provides a convenient shortcut for accessing distant relations via an intermediate relation. For example, a Country model might have many Post models through an intermediate User model. With the help of this method, you can easily gather all blog posts for a given country. You can learn more about this relationship in the official docs:

https://laravel.com/docs/5.5/eloquent-relationships

hasManyThrough will not work with many-to-many relationships. You can use nested whereHas() to get permissions for authenticated user:

Permission::whereHas('roles', function ($q) {
    $q->whereHas('users', function ($q) {
        $q->where('id', auth()->id());
    })
})->get();

And in the comments, you've asked about an inversed solution. If you want to get all users for specified permission, do this:

User::whereHas('roles', function ($q) use($permissionName) {
    $q->whereHas('permissions', function ($q) use($permissionName) {
        $q->where('name', $permissionName);
    })
})->get();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM