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

Ahrengot's avatar

Accessing related model in global query scope

Hey everybody!

I'm working on a global query scope, where I need to access a related model and run some checks on it.

I have projects and comments on those projects.

Let's say my route is /projects/{project}/comments

and my relationship looks like this on the project model:

public function comments()
{
    return $this->hasMany(Comment::class);
}

Now, whenever I load the comments for the projects, I also need to do some additional checks to ensure you can only view all of the comments if you belong to a team with certain permissions.

The permissions part is already taken care of and I can check against it with a custom policy that looks like this $user->can('view-all-comments', $project), but I can't seem to figure out how to determine the parent project via the query builder in the query scope.

My query scope looks like this:

class CommentScope implements Scope
{
    public function apply(Builder $builder, Model $model)
    {
        $user = Auth::user();
        $project = $builder->getRelation('project');

        dd($project);
    }
}

And that dd function returns the following output:

Illuminate\Database\Eloquent\Relations\BelongsTo {#2055 ▼
    #child: App\Models\Comment {#2066 ▶}
    #foreignKey: "project_id"
    #ownerKey: "id"
    #relationName: "project"
    #query: Illuminate\Database\Eloquent\Builder {#1954 ▶}
    #parent: App\Models\Comment {#2066 ▶}
    #related: App\Models\Project {#2067 ▶}
    #withDefault: null
}

So I feel like I'm getting close, but I can't figure out how to get the actual project instance, or at least the project ID, and I need that in order to pass it through to my policy check mentioned before.

0 likes
1 reply
Ahrengot's avatar

Turns out I can grab it in the query scope by looking at the current route:

$route = Route::getCurrentRoute();
if ($route->hasParameter('project')) {
    $project = $route->parameter('project');

    if ($user->can('view-all-comments', $project)) {
        return;
    }
}

Now the next tricky part is this doesn't work with livewire, because on subsequent requests the route isn't there, so this doesn't seem like a good solution.

Please or to participate in this conversation.