count

When working with relationships, most likely you need to get count of related models in many places. There are obvious ways to achieve this of course, but not always efficient. Especially when you are loading a collection of models and their relations.

So let me show you what we can do about it!

hasMany relation

 

1. The most straighforward way would be using one of the two methods below (probably wrapped in a method like getCommentsCount in Post model):

However this is not the best already:

1. $post->comments->count(); loads the collection and returns count of its elements – redundant if all you need is the count.
2. $post->comments()->count(); better, no collection loading, but runs the query everytime we use it.
3. it DOESN’ SCALE 😉 When you need a collection of posts and comments count for each of them, then we end up with n+1 issue, because there’s no way to eager load the count. Of course we can use joins and groupBy and so on, but who cares! Why would you write something like this:

when we prefer nice and elegant syntax a’la Eloquent:

Oh, crap… just spoiled the fun :)
Yes, this is exactly the piece we’re looking for, so let’s get it done already!

 

In order to let Eloquent eager load this thing, we must create a method returning Relation object. And here it is:

 

That basically does the job, however I wouldn’t be myself if I left it just like that:

We saved n queries, but we definitely didn’t save the world…

 

So let’s get it 2 steps forward:

1. Use hasOne instead of hasMany relation in order to avoid returning collection with single item
2. Use accessor in order to easily get the count

 

As noted in the comments by Jeroen Noten Laravel/Illuminate 5.1 introduced relationLoaded method, which does exactly the same as above array_key_exists check, so you can use it instead for verbosity.

With this setup it’s soo nice and easy to work with:

 

And that’s it for hasMany!

Next we’re gonna work with belongsToMany

It's only fair to share...Tweet about this on TwitterShare on RedditPin on PinterestShare on FacebookShare on Google+

Related Post

20 Eloquent tricks – more Recently I stumbled upon interesting article by Povilas Korop on laravel-news 20 eloquent tips and tricks. First of all thanks for sharing your knowle...
A story about Laravel Resources Leo is a brilliant developer. He turns every idea into code in no time. He's prepared for any task thrown at him and dives into coding straight away, ...
How to add custom casters in Laravel tinker I made a series about psysh and Laravel's tinker - powerful REPL where you can play with your whole application. ICYMI check it out here: tinker li...
Too much M4g1c will kill you (or at least bite you... So, as you know, I'm a big fan of Laravel, in particular Eloquent is my favourite. The beauty and value of both is a lot of conventions and magic...