Using scopes with eager loading
Had a situation today where I needed to eager load a relationship but I wanted also wanted utilize a local scope that was defined on the related model I was trying to eager load. Thankfully it turns out this was super easy to add by constraining the eager load.
When using the with
method, we just pass the method an array where the key
is the name of the relationship we want to eager load and the value
is a closure where we can define our constraints. These constrains can include scopes that are defined on the related model!
Here is a basic example where we want to get our Shipping records and eager load the related Order but only if it is fulfilled.
Shipping::with([
"order" => function ($query) {
$query->fulfilled();
}
])->get();
We can do the same when using withWhereHas
. The syntax for this is a little different however. Instead of passing in an array, we instead pass 2, the relationship we want to eager load and a callback where we can again just define our constraints.
In this example we only want to get Shipping records where their related Order record has a status of fulfilled and also eager load that Order.
Shipping::withWhereHas("order", function ($query) {
$query->fulfilled();
})->get();