Reputation: 134
I'm trying to count relationship using a scope to count a filtered part of the relationship
Parent::
withWhereHas('children')
->withCount(['children', function (Builder $builder) {
$builder->where('status', 1);
}])
->get()
The Parent has 36 Children, 6 of them are status = 1 and the variable added is right, i retrieve childens_count = 6.
But i only retrieve the 6 children in the relationship array, whereas i didn't scoped the withWhereHas, so i guess i'm missing something. Is the withCount having any side effect on the whole request ? Didn't see this in the doc.
Here are the relationships in models :
// Programme Model
public function childrens(): HasMany
{
return $this->hasMany(Children::class);
}
// Children Model
public function parent(): BelongsTo
{
return $this->belongsTo(Parent::class);
}
Any suggestion appreciated !
Upvotes: 0
Views: 826
Reputation: 506
From how I understand your question, this is the query that you need to use to retrieve all of the 36 children
$parents = Parent::with('children')->get();
And if you want to set a condition in to children relationship
$parents = Parent::withWhereHas('children', fn($q) => $q->where('status', 1))->get();
// notice i use here foreach looping , because get will return a colletion
foreach ($parents as $parent) {
// to count the children after this query
count($parent->children); // should return 36
}
And if you want to return both children and the counter of a single Parent
$parent = Parent::query()
->withCount('children')
->with('children')
->where('id', 20) // optional , but best to filter which parent
->first(); // this will return a single
// to access how many children
$parent->children_count;
// to access each children
foreach ($parent->children as $child) {
// do something here
}
And if you only want to count all of children, I suggest you use Children.
$children_count = Children::count(); // add filter when needed
EDIT:
To grab all children and yet in the same query showing how many children with status active (1), you can adjust your eloquent query into this:
// I grab only the first Parent with id 1
$parent = Parent::query()
->withWhereHas('children')
->withCount(['children' => fn ($q) => $q->where('status', 1)])
->where('id', 1)
->first();
// this will return all children with any kind of status
$this->assertTrue( $parent->children->count() === 36 );
// this will return counted children with only status active (1)
$this->assertTrue( $parent->children_count === 6 );
note: I have test it in my local test area and work perfectly.
The only difference here is using query() at the beginning.
And of course extra where() and return only the first Parent.
I hope this can help you out.
Upvotes: 1