Sometimes when I'm working on Laravel projects, I want to grab specific models and their relationships, but only if the relationship isn't empty. For example, let's say that in my project, I want to grab all of the
User models as well as eager load their comments; but only the users that have actually commented. To do this, we would need to use the
whereHas methods together in our query.
In this Quickfire post, we're going to take a quick look at the
withWhereHas method and how you can use it to replace separate
whereHas method calls in your queries.
Let's take our example from above and say that we want to grab only the users that have commented; and we also want to eager their comments. To do this, our query might look something like this:
1$usersWithApprovedComments = User::whereHas('comments')2 ->with('comments')3 ->get();
However, with the new
withWhereHas method, we could clean up the query like so:
1$usersWithApprovedComments = User::withWhereHas('comments')->get();
As you can see, this new method provides some syntactic sugar to help improve the readability of our code.
As a side note, if you're unfamiliar with eager loading and how it can prevent N+1 issues in your code, you can check out my How to Force Eager Loading and Prevent N+1 Issues in Laravel article.
Using "withWhereHas" with Callbacks
withWhereHas method also supports callbacks so that you can add extra logic to your eager loading and checks. For example, if we wanted to extend our example queries from above and only fetch the users that had approved comments (and eager only the approved comments), our code might look like this:
1$usersWithApprovedComments = User::whereHas(2 'comments', fn ($query) => $query->where('approved', true)3 )4 ->with([5 'comments' => fn ($query) => $query->where('approved', true)6 ])7 ->get();
We can then improve the code by using the
withWhereHas method like so:
1$usersWithApprovedComments = User::withWhereHas(2 'comments',3 fn ($query) => $query->where('approved', true)4)->get();
In my opinion, I think this method is a really cool addition that helps to reduce the duplication; especially when using the callbacks in the queries.
Hopefully, this short Quickfire post should have given you a brief insight into how you can use the
withWhereHas method in your Laravel applications to reduce duplication.
If you enjoyed reading this post, I'd love to hear about it. Likewise, if you have any feedback to improve the future ones, I'd also love to hear that too.
If you're interested in getting updated each time I publish a new post, feel free to sign up for my newsletter below.
Keep on building awesome stuff! 🚀