Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

laraDev98's avatar

How do I get all Users with Roles where role = 'admin' using eloquent along with Entrust?

I've been using RAW queries but now want to do the right way.Hope you guys will help me!


Role Model

 namespace App\Models;

use Zizaco\Entrust\EntrustRole;
use Illuminate\Database\Eloquent\Model;

class Role extends EntrustRole
{


}

User Model

namespace App\Models;

use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Zizaco\Entrust\Traits\EntrustUserTrait;

class User extends Model implements AuthenticatableContract, CanResetPasswordContract {
    
    use EntrustUserTrait;
    use Authenticatable, CanResetPassword;

    /**
     * The database table used by the model.
     *
     * @var string
     */
    protected $table = 'users';

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['password'];

    /**
     * The attributes excluded from the model's JSON form.
     *
     * @var array
     */
    protected $hidden = ['password', 'remember_token'];


    public function roles()
    {
        return $this->belongsToMany('App\Models\Role');
    }


}

I want to get all the users with their roles like this

name | role

Ryan | admin
Megan | admin

I tried this but doesn't work

$users = User::with('roles')->where('roles.name','=','admin')->get();

Error

Column not found: 1054 Unknown column 'roles.name' in 'where clause' (SQL: select * from users where roles.name = admin)

0 likes
25 replies
RachidLaasri's avatar
$users = User::with(['roles' => function($q){
    $q->where('name', 'admin');
}])->get();
2 likes
RachidLaasri's avatar
$users = User::whereHas('roles' => function($q){
    $q->where('name', 'admin');
})->get();
12 likes
ashwebb's avatar

What does the users table look like? Your query should be something like:

$adminUsers = User::with('roles')->where('role', 'admin')->get();

ashwebb's avatar

@laraDev98 Why do you need to have it be a many-to-many relationship? Would you ever want one user to have more than one role?

ashwebb's avatar

Ok I haven't ever used entrust, but I would try this if I were you.

$users = DB::table('users')->with('roles')->join('roles', 'roles.user_id', '=', 'users.id')->where('roles.name', 'admin')->get();

If you only want the name and role you can add a select, like this:

$users = DB::table('users')->select('users.name as username', 'role.name as role')->with('roles')->join('roles', 'roles.user_id', '=', 'users.id')->where('roles.name', 'admin')->get();
laraDev98's avatar

I know that but I want a cleaner way to fetch it.This looks like CI stuff.

ashwebb's avatar

Ah, well that is my recommendation. It is a very explicit query, which is good practice. You certainly shouldn't feel any need to shy away from such a query. But if you want to run it a a different way, I'll wish you good luck.

ETA: I reread your initial question, and this isn't a raw query.

1 like
laraDev98's avatar

Thanks for your help.Hope some posts the correct way

jekinney's avatar
Level 47

@ashwebb many cases where a user can have multiple roles. Example is forums where a user has a primary role that has basic permissions and a display roll with specific permissions for a particular forum.

Answer to @laraDev98. Run the inverse of the query. Role::with('users')->where('name', 'admin')->get();

9 likes
jekinney's avatar

@laraDev98

Depends on what your result is. For instance you want to list all the users and show which role they have then query the users table as primary.

If you want to display all the roles with associated users, the the role table will be primary.

As far as querying the user table for certain roles isn't an efficient way as generally you'll have a lot more users for your query to cycle through to find the needle in the hay stack. So it can be done, but you should have a good reason for that arguably more expensive query. For entrust I believe you need: User::hasRole('admin')->get();

1 like
jekinney's avatar

Just re-read your last question. Not a rule but it is about utilizing the relationship and efficient queries. Many to many can obviously go either way just fine, when you have many to one a particular schema as mentioned is just to be quick and efficient. Technically speaking it doesn't matter per say which is primary table. But sometimes as in your case, you need to get all users, then loop through each user and loops through the pivot table checking each id to the given role name and getting only the user row with the role. Where the inverse calls a particular role and loops through the pivot table gathering each user id and subsequent user row.

In this case because your comparing a string in roles table to fetch a role id, then looking at the pivot table to get each user id, then the user table to get each row.

1 like
TheSource's avatar

I don't know if you still have this problem, but I had the same problem and I did it this way:

Role::where('name', 'admin')->first()->users()->get()

So what it does. First get the Role model object that has a name of "admin" and then get the related users, using the belongsToMany relationship from Laravel.

Maybe this way works better for you.

5 likes
SwissCoder's avatar

I realize this is an old thread and my answer is unrelated to Entrust but this works with Laravel's UserHasRoles:

$admins = User::whereHas('roles', function($q){$q->whereIn('role_name', ['administrator']);})->get();

HTH

5 likes
dkruger's avatar

@laraDev98 sorry if this is a long, long looooong delay. I tested some options and for the zizaco I use this approach based on @RachidLaasri

$users = User::whereHas('roles', function($q){
    $q->where('name', 'admin');
})->get();
3 likes
Yunus.work's avatar
 $users = User::whereHas('roles', function ($q) {
       //conditions from role table
            $q->Where('name', 'admin')->
                orWhere('name', 'physician');

        })->
           // conditions from Usertable
          where('active_status', 1)->paginate(20);

I know you got your answer, may be another guys use it.

1 like
skeith22's avatar

This is the answer

User::whereHas('roles', function ($query) {
    $query->where('id', 1);
});
1 like
letscms's avatar

Hi I know this is very late but it may help someone to get users list.

There are two ways as:

  1. $admins=User::whereHas('roles', function($q){$q->where('name', 'admin');})->get();
  2. $admins=User::whereHas('roles', function($q){$q->whereIn('roles.name', ['admin']);})->get();
rajwanraju's avatar

I would like to say like this....

$admins = User::whereHas('roles', function($q){$q->whereIn('roles.name', ['admin']);})->get();

dd($admins);

And i got my result.....

YuraSk's avatar

@helvetian answer worked for me in laravel 5.5

$clients = User::whereHas('roles', function($q){$q->whereIn('name', ['client']);})->get();

1 like
danfebra's avatar
User::whereHas('roles', function($q) {
        $q->whereName('insert_name_of_role');
    })->get();

This gives you all the users with the certain role you're looking for.

Please or to participate in this conversation.