55

I'm ideally looking for a function like

load('relationship')

but which loads a count in the same way

withCount('relationship')

works for eager loading.

I'm thinking it is going to be called loadCount('relationship')

Edward Louth
  • 1,010
  • 2
  • 9
  • 19

3 Answers3

75

loadCount() is available since Laravel 5.8

$post->loadCount('comments');

$post->comments_count;

Docs

Maksim Ivanov
  • 3,991
  • 31
  • 25
37

As of Laravel 5.2, this functionality is built-in.

Provided you have a hasMany relationship between Post and Comment, do:

<?php

$posts = App\Post::withCount('comments')->get();

foreach ($posts as $post) {
    echo $post->comments_count;
}

You can even eager load relationships count by default by declaring this in your model:

<?php

// Post model

protected $withCount = ['comments'];
rzb
  • 2,077
  • 6
  • 22
  • 31
  • 2
    This is all true, however I was looking for lazy eager loading ([see](https://laravel.com/docs/5.5/eloquent-relationships#lazy-eager-loading)), i.e. being able to load a count after the model has already been retrieved. – Edward Louth Jan 29 '18 at 09:18
  • 1
    No the accepted answer is totally right for lazy loading counts – shigg May 16 '18 at 01:50
  • 3
    @shigg Except that it's not lazy loading anything. The count query is performed at the same time as the main query, meaning it's being eager loaded. Which Laravel supports by default as I demonstrated above. – rzb May 16 '18 at 02:19
16

This solution works great for me:

Create a new hasOne relationship on the related model and add a raw select to the query for the count. For example, if you want to eager load the number of tasks for a given user, add this to the User Model:

public function taskCount()
{
    return $this->hasOne('App\Task')
    ->selectRaw('user_id, count(*) as count)
    ->groupBy('user_id');
}

And then eager load the count like this:

$user = User::where('email', $email)->with('taskCount')->first();

And access the count like this:

$taskCount = $user->task_count->count;
bicycle
  • 8,315
  • 9
  • 52
  • 72
hubrik
  • 999
  • 7
  • 6