Introducing Laravel Quizzes! Play now

Refactoring with Laravel's new whereRelation methods

Refactoring with Laravel's new whereRelation methods


Prior to this simple PR, we needed verbose closures to do simple queries on relationships. Now it can be done on one line with these simple helpers.

This is how you would currently query the relationship on a model to narrow down your results.

// Get me all users who have posts that are to be published in the future.
User::whereHas('posts', function ($query) {
    $query->where('published_at', '>', now());
})->get();

With this new PR, we can now refactor and simplify the above to the following:

User::whereRelation('posts', 'published_at', '>', now())->get();

As you can see, we have collapsed the closure into the parameter list of the whereRelation method.

With this PR, you also have access to orWhereRelation, whereMorphRelation, and orWhereMorphRelation.

It is worth noting that because it uses a where clause under the hood, it would not be possible to use scopes:

User::whereHas('posts', function ($query) {
    $query->notPublished();
})->get();

Or nested where:

User::whereHas('posts', function ($query) {
    $query
        ->whereHas('tags', function ($query) {
            $query->where('name', 'Laravel');
        })
        ->where('published_at', '>', now());
})->get();

Though you should be able to use nested relations if you don't have any intermediate where clauses:

User::whereRelation('posts.tags', 'name', 'Laravel')->get();
Anthony Rappa

By Anthony Rappa

Hello! I'm a full stack developer from Long Island, New York. Working mainly with Laravel, Tailwind, Livewire, and Alpine.js (TALL Stack). I share everything I know about these tools and more, as well as any useful resources I find from the community. You can find me on GitHub and LinkedIn.