Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Eager loading related model using query scope

Say I have a model Box which holds many widgets. The widgets can be active or inactive (boolean). The Widget model has a query scope which can filter results:

models/box.php:

class Box extends Eloquent
{
    public function widgets()
    {
        return $this->hasMany('Widget');
    }
}

models/widget.php:

class Widget extends Eloquent {

    public function box()
    {
        return $this->belongsTo('Box');
    }

    public function scopeActive($query)
    {
        return $query->whereActive(true);
    }
}

Query scopes make it easy to get all widgets for a given box:

$box_widgets = Box::find($box_id)->widgets()->active()->get(); 
// returns an Eloquent\Collection containing a filtered array of widgets

But how can I use scopeActive to eliminate this eager loading with method's conditional function?

$boxes = Box::with(array('widgets', function ($q)
{
    $q->active();
}))->get();

It seems like there's probably a shorthand for accessing a relation's scope, something like Box::with('widgets->active') or Box::with('widgets.active') but I haven't been able to find it.

like image 778
joemaller Avatar asked Apr 08 '14 15:04

joemaller


1 Answers

Suppose most of the time you want only active widgets, so I suggest:

public function widgets()
{
    return $this->hasMany('Widget')->whereActive(true);
}

public function widgetsDisabled()
{
    return $this->hasMany('Widget')->whereActive(false);
}

You can setup up more, for example for loading all at once, like you have now.

Then eager load as easily as that:

Box::with('widgets')... // loads only active
like image 95
Jarek Tkaczyk Avatar answered Sep 29 '22 05:09

Jarek Tkaczyk