Using scopes with eager loading

October 02, 2024

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();

© 2024 Terrence Eisenhower. All rights reserved.