Tengo un modelo, llamémoslo Parent .
Cada Parent puede tener muchos hijos.
public function children(): HasMany { return $this->hasMany(Child::class, 'parent_id', 'id'); } Quiero crear un alcance para Parent llamado "activo".
Mi requerimiento es el siguiente:
El padre está activo cuando tiene al menos 1 hijo.
He realizado alcances locales varias veces y sé que dentro de Parent.php puedo hacer algo como:
public function scopeActive($query) { return $query->where(…); } Pero como puede ver, $query es \Illuminate\Database\Eloquent\Builder , que no es mi caso. Quiero operar en un modelo relacionado de alguna manera, no en la consulta DB.
¿Puedo hacer esto de una manera limpia sin buscar a todos los padres with('child') y dentro de ->filter() olvidando aquellos que no tienen hijos? Cuando habrá 1000 padres pero solo uno tendrá hijos, simplemente desperdiciará recursos de DB (obteniendo 999 padres redundantes).
Puedes usar la siguiente consulta
public function scopeActive($query) { return $query->has('children'); }Una opción es usar whereHas en el alcance:
public function scopeActive($query){ return $query->whereHas('children'); }O
public function scopeActive(){ return $this->whereHas('children'); }Y
Parent::active()->with('children')->get();debe darle todos los padres que tienen hijos y junto con los respectivos hijos
¿Puedes intentar algo como:
public function getActiveAttribute() { return $this->children()->count() > 1; }Esto se puede usar como,
$parent->active Y la consulta solo se realizará cuando intente acceder a la propiedad active en el Parent principal, no cuando busque todos los principales.