Laravel-permission: How To Get Users by Role/Permission

Created on 8 Mar 2018  路  11Comments  路  Source: spatie/laravel-permission

I am planning on using this additionally to create some user lists by role - for example, list all users in a given department. This could also be useful to get all users with a given permission, but that isn't as important for me currently.

Is there a built-in method to enumerate users in a given role, or should this be accomplished with a raw query on the tables?

support

Most helpful comment

For anyone looking for another way to do this:

User::whereHas("roles", function($q){ $q->where("name", "Member"); })->get()

All 11 comments

Nothing special required, since the data is all in Eloquent models.

Role has a users relationship, so $role->users gives a collection of related objects.
Users has a roles relationship, so $user->roles gives a collection of roles.

Example controller method, where it also filters for a set of "non-members" based on role, is :

    public function report_roles()
    {
        $roles = Spatie\Permission\Models\Role::all();
        $users = \App\User::with('roles')->get();
        $nonmembers = $users->reject(function ($user, $key) {
            return $user->hasRole('Member');
        });
        return view('admin.report_roles', ['roles'=>$roles, 'nonmembers' => $nonmembers]);
    }

and corresponding view:

  <div class="container">
    <div class="row">
      <div class="col-md-5 col-md-offset-1">

        <div class="panel panel-default">
          <div class="panel-heading panel-title">Role Assignments</div>
          <div class="panel-body">

            <p>Available roles:</p>
            @foreach($roles as $r)
              @if($r->name == 'Member')
                @continue
              @endif
              <ul class="listBox">
                <li>{{$r->name}}
                  <ul class="listBox">
                    @foreach ($r->users as $u)
                      <li>{{$u->name}}</li>
                    @endforeach
                  </ul>
                </li>
              </ul>
            @endforeach
          </div>
        </div>
      </div>

      <div class="col-md-5">

        <div class="panel panel-default">
          <div class="panel-heading panel-title">Role Assignments</div>
          <div class="panel-body">

            <p>Users WITHOUT "Member" role:</p>
            <ul class="listBox">
              @foreach($nonmembers as $u)
                <li><a href="/members/{{ $u->id }}">{{ $u->name }}</a> ({{ $u->weekend }})</li>
              @endforeach
            </ul>
          </div>
        </div>


      </div>
    </div>
  </div>

Very helpful, thank you!

For anyone looking for another way to do this:

User::whereHas("roles", function($q){ $q->where("name", "Member"); })->get()

Thanks @jonaselan

For anyone looking for "get all roles but exclude specific role":

Example I have 3 roles which are ['Administrator','Instructor','Student'] and I wanna exclude 'Student' role from the collection.
Then I can use filter function.

$roles = Spatie\Permission\Models\Role::all();
$roles->filter( function($item){ return $item->name != 'Student'; });

Output: ['Administrator','Instructor']

For anyone looking for another way to do this:

User::whereHas("roles", function($q){ $q->where("name", "Member"); })->get()

What is "Member" in this case? Is the "Member" role name?

So for users with admin role for example we would do it like this:

User::whereHas("roles", function($q){ $q->where("name", "admin"); })->get()

to get all users that have admin role. Is this correct?

@hardcoremore yep

Semi related, if you just require a count of users within a role, where a single query is executed:

// $role is the required role by name i.e. 'Staff' User::whereHas('roles', function (Builder $query) use ($role) { $query->where('name', $role); })->count()

or, you can directly use, its method,

User::role('writer')->get()

will return users having writer role.

For anyone looking for "get all roles but exclude specific role":

Example I have 3 roles which are ['Administrator','Instructor','Student'] and I wanna exclude 'Student' role from the collection.
Then I can use filter function.

$roles = Spatie\Permission\Models\Role::all();
$roles->filter( function($item){ return $item->name != 'Student'; });

Output: ['Administrator','Instructor']

To get all roles and exclude some of them I found also this option, and in this way, you can pass even an array of roles to exclude.

Role::whereNotIn('name', ['Student', 'another role to exclude'])->get();

Good point. Yes, there are many Eloquent helpers that can help with such filtering.
A few more are listed at: https://spatie.be/docs/laravel-permission/v3/basic-usage/basic-usage#eloquent

Was this page helpful?
0 / 5 - 0 ratings

Related issues

enghelewa picture enghelewa  路  4Comments

tripex picture tripex  路  3Comments

neoreids picture neoreids  路  3Comments

feliperoan picture feliperoan  路  3Comments

ghost picture ghost  路  3Comments