Laravel Eloquent relationships have a bunch of “with” methods you might not know about.

Warrick Bayman
3 min readFeb 17, 2022
Photo by Joshua Earle on Unsplash

This post was was originally published on THEPUBLICGOOD blog. You can find it here.

Eloquent is the database ORM that is included with Laravel. Taylor Otwell recently stated that it’s one of the most complex pieces of Laravel to maintain. Yet it’s probably one of the most important reasons why Laravel has become so super popular.

You may already have a good handle of how Eloquent works and there’s a bunch of useful tools that are included. One those tools you might already know about is the withCount method. This is really handy if you need to include a count of a related model. Let’s say you have a User and Post model and want to include the number of posts per user when making a query. You would probably have your User model set up with a posts() method like this:

public function posts(): HasMany
{
return $this->hasMany(Post::class);
}

Your Eloquent query would then look something like this:

$users = User::withCount('posts')->get();

Eloquent will automatically build up the queries for you so that you get the number of posts per user included in the resulting model instance, which you can get to like this:

$posts = $users->first()->posts_count;

But did you know that there are a few more than just withCount?

withMax and withMin

withMax and withMin methods can be used to get the maximum or minimum value of an attribute on the related model. Using the example from above, let's say posts have a rating. You might want to know what the highest, or the lowest rating is across all the users posts.

// Get the highest rating
$max = User::withMax('posts', 'rating')->get();

// Or the lowest rating
$min = User::withMin('posts', 'rating')->get();

Eloquent will include a posts_max_rating or a posts_min_rating on the User model instance. You can even rename the attribute if you want by using the “as” syntax like this:

$max = User::withMax(‘posts as max_rating’, ‘rating’)->get();

withSum

Similarly, you can use the withSum method to get the total value of all the ratings added together.

$total = User::withSum('posts as total_rating', 'rating')->get();

You’d get a posts_sum_rating attribute on each User instance.

withAvg

The withAvg method is really handy if you need to know what the average rating is across multiple relations. For a recent project we needed to know what the rating was of a list of contacts. Each contact was giving a health rating out of 100 and we wanted to give the list a rating as well based on the health of each contact. We can get the average rating across all the contacts on the list in one query using the withAvg method:

$contacts = ContactList::orderBy('title')
->withAvg('contacts as rating', 'rating')
->get();

This gives us a rating attribute on every ContactList model instance. We didn’t need to do any math in our code. The database did the heavy lifting for us and we got the results we needed.

--

--

Warrick Bayman

Programmer, musician, cyclist (well... I own a bike), husband and father.