Refactoring to whereRelation method
Eduar Bastidas • September 7, 2021
tips refactoringPreviously in Laravel when you wanted to get a relation and include an extra complex condition you had to do it with the whereHas
method in the following way:
1// Get me all users who have posts that are to be published in the future.2User::whereHas('posts', function ($query) {3 $query->where('published_at', '>', now());4})->get();
Recently DarkGhostHunter has made a PR in Laravel 8.57.0 version where it is possible to simplify this in a much more elegant and polished way.
1User::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 whereRelation
and orWhereRelation
helpers, and whereMorphRelation
and orWhereMorphRelation
for morph relations. Since these use the where
method underneath, you can do advanced things:
1Comment::whereMorphRelation('commentable', '*', [2 'is_public' => true,3 'is_vip' => false,4])->get();
What cannot be done
However, it also becomes a disadvantage, since you will not be able to use scopes inside as you used to do with whereHas
, for example you will not be able to make
1Post::whereHas('comments', function ($comment) {2 $comment->approved();3})->get();
Or nested where:
1User::whereHas('posts', function ($post) {2 $post->whereHas('tags', function ($tag) {3 $tag->where('name', 'tips');4 })->where('published_at', '>', now());5})->get();
This is an improvement that many of us will appreciate very much and that will serve us in the day to day to have a more elegant code without a doubt.