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?
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
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
Most helpful comment
For anyone looking for another way to do this: