Laravel-permission: Question: get users has not role X

Created on 20 Feb 2019  路  8Comments  路  Source: spatie/laravel-permission

Hello,

How to get the list of users that has not role "x" and "y" ?

Thank you

support

Most helpful comment

Add this to your user model:

    public function scopeNotRole(Builder $query, $roles, $guard = null): Builder 
    { 
         if ($roles instanceof Collection) { 
             $roles = $roles->all(); 
         } 

         if (! is_array($roles)) { 
             $roles = [$roles]; 
         } 

         $roles = array_map(function ($role) use ($guard) { 
             if ($role instanceof Role) { 
                 return $role; 
             } 

             $method = is_numeric($role) ? 'findById' : 'findByName'; 
             $guard = $guard ?: $this->getDefaultGuardName(); 

             return $this->getRoleClass()->{$method}($role, $guard); 
         }, $roles); 

         return $query->whereHas('roles', function ($query) use ($roles) { 
             $query->where(function ($query) use ($roles) { 
                 foreach ($roles as $role) { 
                     $query->where(config('permission.table_names.roles').'.id', '!=' , $role->id); 
                 } 
             }); 
         }); 
    }

You can use it like this:

$users = User::notRole('Admin')->get();
$users = User::notRole(['Admin', 'Super Admin'])->get();

This might help you. Let me know if it's not working.

All 8 comments

The package currently offers a roles scope to let you find users which DO have the specified roles:
https://github.com/spatie/laravel-permission/blob/087a53cf8ec0cf79ad326f612b0d171364f0d9b6/src/Traits/HasRoles.php#L51-L88

You could rework your logic to work with that (either to determine a "with" instead of "without" logic flow, or simply grab a collection of all the "other" roles and pass that to the scope), or you could add your own scope to your model to perform the reverse "not" lookup.

@drbyte alright thank you, I need this for feature testing.

Add this to your user model:

    public function scopeNotRole(Builder $query, $roles, $guard = null): Builder 
    { 
         if ($roles instanceof Collection) { 
             $roles = $roles->all(); 
         } 

         if (! is_array($roles)) { 
             $roles = [$roles]; 
         } 

         $roles = array_map(function ($role) use ($guard) { 
             if ($role instanceof Role) { 
                 return $role; 
             } 

             $method = is_numeric($role) ? 'findById' : 'findByName'; 
             $guard = $guard ?: $this->getDefaultGuardName(); 

             return $this->getRoleClass()->{$method}($role, $guard); 
         }, $roles); 

         return $query->whereHas('roles', function ($query) use ($roles) { 
             $query->where(function ($query) use ($roles) { 
                 foreach ($roles as $role) { 
                     $query->where(config('permission.table_names.roles').'.id', '!=' , $role->id); 
                 } 
             }); 
         }); 
    }

You can use it like this:

$users = User::notRole('Admin')->get();
$users = User::notRole(['Admin', 'Super Admin'])->get();

This might help you. Let me know if it's not working.

@biholaindrasinh This should be included in the original permissions package.. Much needed function.

@biholaindrasinh not working.

You can use basic built-in Laravel Eloquent functions such as doesntHave() as documented here:
https://docs.spatie.be/laravel-permission/v3/basic-usage/basic-usage/
and in the Laravel documentation.

@drbyte Yes, That's the solution what I found. Thanks.

$users = User::notRole('Admin')->get();

Why I got this error:

Call to undefined method App\User::notRole()

Any suggestion @biholaindrasinh ?

Thanks in advance.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

holymp2006 picture holymp2006  路  4Comments

ionesculiviucristian picture ionesculiviucristian  路  4Comments

dylangeorgeharbour picture dylangeorgeharbour  路  3Comments

MichalKrakow picture MichalKrakow  路  4Comments

NattananWs picture NattananWs  路  3Comments