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

vincent15000's avatar

Query has() with can()

Hello,

I have this code.

->when($filters['with_at_least_two_events'], function ($query) use ($filters) {
    if ($filters['with_at_least_two_events']) {
        $query->has('events', '>=', 2);
    }
})

Is it possible to apply a policy to take into account only the events that the connected user can see ?

I need to have something like this.

$query->has('events', '>=', 2);

// only if the connected user can see the events

if (auth()->user()->can('view', $event))

I had the idea to use whereHas() instead of has(), but how is it possible to check each event ?

Thanks for your help.

V

0 likes
8 replies
tykus's avatar

It depends what determines the view permission; how is the ability determined; in a Policy method?

1 like
vincent15000's avatar

@tykus These are not only permissions ... it's related to some business logic.

return
    ($event->results->where('user_id', $user->id)->count() > 0)
    && (
            $user->hasCreatedTheEvent($event)
            || $user->hasBeenInvitedToTheEvent($event)
        )
    );

Perhaps it's not the best place to manage this kind of permissions ? If this is the case, where would you write this logic ?

tykus's avatar

@vincent15000 ok... the problem is you are not working with Event instances in the context of your Builder filter; so the User methods (hasCreatedTheEvent and hasBeenInvitedToTheEvent) are not going to be useful in this context.

Instead, you will need to replicate these methods (and the results count) in the whereHas Closure using a combination of joins. Aside, assuming you have not eager-loaded the results, this

$event->results->where('user_id', $user->id)->count() > 0

would be more performant as a query:

$event->results()->where('user_id', $user->id)->count() > 0
1 like
vincent15000's avatar

@tykus Oh sorry these are not events (events / listeners) but events in a cultural context.

Your solution could be a good idea, but for example a User with a specific role can see the results of another User with another role.

The example is more complex that what I have shown here.

Is there a possibility to use at the same time whereHas() and can() ? If not, I will write the code another way.

tykus's avatar
tykus
Best Answer
Level 104

@vincent15000

these are not events (events / listeners) but events in a cultural context.

This was understood from the outset.

Is there a possibility to use at the same time whereHas() and can() ? If not, I will write the code another way.

Not really; whereHas is Eloquent Builder, whereas can (when instance specific - view rather than viewAny) needs the Model instance.

1 like
vincent15000's avatar

@tykus I hoped it was possible, it would has been great ;).

I will try another approach to apply the authorizations, I will simply filter the retrieved collection according to the authorizations.

Please or to participate in this conversation.