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

p3drojimenez's avatar

Filament globalScope for tenant and public website

Hello, I am creating a directory or listing app SaaS using Filament and I am super happy and excited. It fits everything I need except for one thing, and that is a matter of tenancy. In all models, I have something like addGlobalScope, and at the user level, it works well, now I have to add the condition, is_admin returns all fields. This at the admin panel level works well. The problem comes in that I use those same models to display the information on the web. When I make a query with a user not logged in, the results are correct, when the user is logged in, logically they are filtered on the public web and it is not correct.

I would need to create some kind of middleware or I don't know how or where to add it so that only the globalScope is added for the admin panel. Something like:

is_admin or is_from_web, that does not filter the fields by team_id or user_id.

Do you know how this can be done? Another way is to duplicate Models but it seems like a mistake and would complicate the scalability of the product.

Thank you!

0 likes
2 replies
aurawindsurfing's avatar

Hey @p3drojimenez

Its long time and you probably figured it out but if it is the same resource then:

->visible(fn (Post $record): bool => auth()->user()->can('update', $record))

or simply

->visible(fn (Post $record): bool => auth()->user->team_id === 2)

Hope it helps!

markomo's avatar

I would not suggest using ->visible(...) becuse that only hides field using CSS, data is still there and that is the problem. @p3drojimenez I've just delth with same thing over last 2 days by setting different scopes and removing scopes. Example:

Assuming you have set globalScope in your booted with name "allowed"

use Illuminate\Database\Eloquent\Builder;
// in your Model class
class MySimpleTestModel extends Model
{
    protected static function booted()
    {
        /**
         * Adds a global scope to filter the query by the authenticated user's company ID.
         *
         * @param  \Illuminate\Database\Eloquent\Builder  $query
         * @return void
         */
        static::addGlobalScope('allowed', function ($query) {
            // Just an example of how to use for all users as general scope
            $query->where('allowed_to_see_me', !auth()->user()->is_admin)
            ->where('is_from_web', true);
        });
		// You can specify as many parameters as you need or NONE if you don't need it (assuming you will need)
        public function scopeOnlyAdmin(Builder $query, string $your_filter = null, $limit = 10) 
        {
            // just admins
            $query->where('allowed_to_see_me', auth()->user()->is_admin);
           //  build your query as needed ->where(.....);  
            
        }
    }
}

Then in your Resource you can exclude scope where you need to show something to admin in your query by using:

Keep note on this: ofOnlyAdmin starts with "of" where scope function name is "scopeOnlyAdmin". As well on removing scope "withoutGlobalScope" in example below.

// MySimpleTestModel::ofOnlyAdmin()  if you don't have any extra parameters
$products = MySimpleTestModel::ofOnlyAdmin($filter, $limit)->withoutGlobalScope('allowed')
   ->get()
   ->toArray();

You can extend logic and add multiple scopes and exclude multiple of them in chain if needed. I hope this helps.

Resource: https://laravel.com/docs/10.x/eloquent#removing-global-scopes

Please or to participate in this conversation.