Skip to content

Instantly share code, notes, and snippets.

@DominikStyp
Last active January 23, 2024 16:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DominikStyp/d6db57848d76ee96a40220f54f67c0b1 to your computer and use it in GitHub Desktop.
Save DominikStyp/d6db57848d76ee96a40220f54f67c0b1 to your computer and use it in GitHub Desktop.
Laravel 10 Model: Use query builder to filter User roles

How to easily query permissions/roles

Requirements

  • Spatie Permissions Package
  • Laravel 10

Explanation

When we query 'roles' in fact we use the model method :

    /**
     * A model may have multiple roles.
     */
    public function roles(): BelongsToMany
    {
        $relation = $this->morphToMany(
            config('permission.models.role'),
            'model',
            config('permission.table_names.model_has_roles'),
            config('permission.column_names.model_morph_key'),
            PermissionRegistrar::$pivotRole
        );

        if (! PermissionRegistrar::$teams) {
            return $relation;
        }

        return $relation->wherePivot(PermissionRegistrar::$teamsKey, getPermissionsTeamId())
            ->where(function ($q) {
                $teamField = config('permission.table_names.roles').'.'.PermissionRegistrar::$teamsKey;
                $q->whereNull($teamField)->orWhere($teamField, getPermissionsTeamId());
            });
    }
<?php
declare(strict_types=1);
namespace App\Models;
use App\Models\Passport\Client;
use Database\Factories\UserFactory;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\HasOneThrough;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;
use Laravel\Passport\HasApiTokens;
use Spatie\Permission\Traits\HasRoles;
/**
* @mixin IdeHelperUser
*/
class User extends Authenticatable implements \OwenIt\Auditing\Contracts\Auditable, IdentityEntityInterface
{
use HasFactory, Notifiable, HasApiTokens, SoftDeletes, HasRoles;
/**
* This produces following SQL:
select * from `users` where (
exists (
select * from `permission_roles`
inner join `permission_model_has_roles` on `permission_roles`.`id` = `permission_model_has_roles`.`role_id`
where `users`.`id` = `permission_model_has_roles`.`model_id`
and `permission_model_has_roles`.`model_type` = 'App\\Models\\User'
and `permission_roles`.`name` not in ('root')
)
or not exists (
select * from `permission_roles` inner join `permission_model_has_roles`
on `permission_roles`.`id` = `permission_model_has_roles`.`role_id`
where `users`.`id` = `permission_model_has_roles`.`model_id`
and `permission_model_has_roles`.`model_type` = 'App\\Models\\User'
)
) and `users`.`deleted_at` is null
*/
public function scopeNonRootUser(Builder $query): Builder
{
return $query->whereHas('roles', function (Builder $builder){
$builder->whereNotIn('permission_roles.name', ['root']);
})->orWhereDoesntHave('roles');
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment