I have a model - let's call it Parent.
Each Parent can have many children.
public function children(): HasMany
{
return $this->hasMany(Child::class, 'parent_id', 'id');
}
I want to make a scope for Parent called "active".
My requirement goes as follows:
Parent is active when it has at least 1 child.
I've done local scopes multiple times and I know that within Parent.php I can do something like:
public function scopeActive($query)
{
return $query->where(…);
}
But as you see, $query is a \Illuminate\Database\Eloquent\Builder which is not my case. I want to operate on related model somehow, not the DB query.
Can I do this in a clean way without fetching all parents with('child') and within ->filter() forgetting those that have no children? When there will be 1000 parents but only one will have children, it will simply waste DB resources (by fetching 999 redundant parents).
You can use the following query
public function scopeActive($query)
{
return $query->has('children');
}
One option is to use whereHas in scope:
public function scopeActive($query){
return $query->whereHas('children');
}
OR
public function scopeActive(){
return $this->whereHas('children');
}
And
Parent::active()->with('children')->get();
should give you all Parents who have children and along with respective children
Can you try something like:
public function getActiveAttribute() {
return $this->children()->count() > 1;
}
This can be used like,
$parent->active
And the query will only be made when you'll try to access the active property on the Parent model, not when you will be fetching all parents.