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

uicabpatweyler's avatar

Advanced query with Eloquent, using Scopes

I am using spatie/laravel-permission to manage roles and permissions. In the list of roles I want to make a personalized query based on the role of the current, authenticated user.

Rule 1) If the user has the role of Super Admin, all roles are filtered without exception.

Rule 2) If the user has the Administrator role, the roles are displayed, except the Super Admin.

My models are: User and Role. Something like this has occurred to me, in my RoleController.php

if(Auth::user()->hasRole('Super Admin'))
{
    // execute a query for get all roles
}
else
{
    //execute a query for get the roles, except the rol of Super Admin
}

For now, I get all the roles and in the view I apply permission-based conditions.

Reviewing the documentation of Laravel, I note that this query can be simplified using an advanced query together scope's.

How could I do it? Thanks for your help

0 likes
6 replies
tykus's avatar
tykus
Best Answer
Level 104

You can use the when Builder method to set the constraints depending on truthiness (or otherwise) of an expression:

Role::when(
    Auth::user()->hasRole('Super Admin'),  // truth test
    function ($builder) {
        // modify the query based on the expression being true
    },
    function ($builder) {
        // modify the query based on the expression being false
    },
)->get();

How you modify the query (whether using scopes or otherwise) depends on the complexity and/or reusability of those queries.

Snapey's avatar

get all roles, and reject the Super Admin

Role::all()->reject(function($role) {
    return $role->name=='Super Admin';
});

Snapey's avatar

get all roles from database except the one you don't want

Role::where('name','!=','super admin')->get()
Snapey's avatar

Get all roles then reject only if they are super admin

$roles =Role:all();

if(Auth::user()->hasRole('Super Admin') {
    $roles->reject(function($role) {
        return $role->name=='Super Admin';
    });
}

No need for else condition

bugsysha's avatar
Model::when(Auth::user()->hasRole('Super Admin') === false, function (Builder $query) {
        return $query->where()...
    })
    ->get();

I've wrote Auth::user()->hasRole('Super Admin') === false just to make it explicit and obvious. But you can use !Auth::user()->hasRole('Super Admin') to make it cleaner.

If you are using PHP7.4

Model::when(Auth::user()->hasRole('Super Admin') === false, fn (Builder $query) $query->where()...)->get();

Please or to participate in this conversation.