Reputation: 18834
From my controller I would like to select all of the users that have the role "client".
I have a User model and a Role model. A role belongs to many users and a user belongs to many roles.
I've established my models and have some helper functions at the model instance level for fetching roles and users
Here are the User and Role database models:
app/User.php
class User extends Authenticatable
{
use Notifiable;
protected $fillable = [
'name', 'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
// User belongs to many roles
public function roles()
{
return $this->belongsToMany('App\Role')->withTimestamps();
}
// whitelist specific roles
// reject if user does not have given roles
public function authorizeRoles($roles)
{
if ($this->hasAnyRole($roles)) {
return true;
}
abort(401, 'This action is unauthorized.');
}
// Check if a user has a role
public function hasRole($role)
{
if ($this->roles()->where('name', $role)->first())
{
return true;
}
return false;
}
// Pass in string or array to check if the user has a role
public function hasAnyRole($roles)
{
if (is_array($roles)) {
foreach ($roles as $role) {
if ($this->hasRole($role)) {
return true;
}
}
} else {
if ($this->hasRole($roles)) {
return true;
}
}
return false;
}
}
app/Role.php:
class Role extends Model
{
public function users()
{
return $this->belongsToMany('App\User')->withTimestamps();
}
}
I have migrations for a create_users_table, create_roles_table and a pivot table for create_role_user_table. Each role has an id, name and description. Each user has an id, name, email and password.
I would like to filter by all users that have the role called "client".
In my controller method I try to call roles but it does not work because it is an instance method:
// Display admin dashboard
public function admin(Request $request)
{
// check to make sure user is an admin
$request->user()->authorizeRoles('admin');
// Display all users that have the role "client"
// ***** section that does not work ********
$users = User::all()->roles()->where('name', 'client')->get();
return view('admin', compact('users'));
}
How can I populate the $users
variable with only users who have the role with name "client"?
Upvotes: 3
Views: 5129
Reputation: 163748
Use whereHas()
method:
User::whereHas('roles', function ($q) use ($roleName) {
$q->where('name', $roleName);
})->get();
Upvotes: 8