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?
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
}]);
}]);