Home > database >  laravel withcount changes relationship result
laravel withcount changes relationship result

Time:01-29

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.

Any suggestion appreciated !

CodePudding user response:

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

I hope this can help you out.

CodePudding user response:

Add this relation to the Parent class

public function all_children(){
  return $this->hasMany(Parent::class, 'parent_id', 'id');
}
public function active_children(){
  return $this->hasMany(Parent::class, 'parent_id', 'id')
   ->where('status',1);
}

public function inactive_children(){
  return $this->hasMany(Parent::class, 'parent_id', 'id')
  ->where('status',0);
}

then

Parent::withCount('active_children')->get();
  • Related