Search code examples
laravellaravel-11

How to use loadCount?


I have Factory which hasMany Category which hasMany Product in my model. So for example the Category looks like this:

class Category extends Model
{
    use HasFactory;

    public function products(){
        return $this->hasMany(Product::class);
    }

    // ...
}

I am trying to list the categories and I want to add the count of products to each category on this list.

What I am doing currently is

    $factories = Factory::all();
    $factories->load('translation');
    $factories->load('categories');
    $factories->load('categories.translation');
    $factories->load('categories.products');

Now the problematic part that I don't want to load the complete product list, just the count of the products. I found that there is this loadCount method, which should do exactly what I need, though I am not sure how to use it.

When I do $factories->loadCount('categories.products'), then I got an error message: "Call to undefined method App\Models\Factory::categories.products". Not to mention that I am not sure how to get just the count without lazy loading the whole thing just by accessing products. Can somebody explain how this is supposed to work?


Solution

  • First you should use eager loading even if in this case it doesnt change performance much but with it we can use withCount() method

    $factories = Factory::query() //using query() first is IDE friendly
        ->with([
            'transalation',
            'categories' => function($category) {
                $category->withCount('products')->with('translation');
            },
        ])->get();
    

    This will return the same result as your code example without the loaded products and add on each category the attribute product_count with the count of its products.

    If you have a scope or something to filter the products over, you do it like this

    $factories = Factory::query() //using query() first is IDE friendly
        ->with([
            'transalation',
            'categories' => function($category) {
                $category
                    ->with('translation')
                    ->withCount(['products' => function($product) {
                        $product->where('active',true); //or ->active() if its a scope
                    }]);
            },
        ])->get();
    

    Using load eager loading

    $factories = Factory::all();
        $factories->load('translation');
        $factories->load(['categories' => function($category) {
            $category
                ->with('translation')
                ->withCount(['products' => function($product) {
                    $product->where('active',true); //or ->active() if its a scope
                }]);
        }]);