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 to 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 a model. Let's say you have a
Post model and want to include the number of posts per user when making a query. You would normally have set up your
User model with a
posts() method like this:
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 the number of posts per user are included in the resulting model instance. You'd be able to get to the posts count like this:
$posts = $users->first()->posts_count;
But did you know that there are a few more than just
withMax and withMin
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 the posts can 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 doing something like this:
$max = User::withMax('posts as max_rating', 'rating')->get();
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
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
$contacts = ContactList::orderBy('title') ->withAvg('contacts as rating', 'rating') ->get();
This gave us a
rating attribute on every
ContactList model instance. We didn't need to do any math in the application. The database did the heavy lifting for us and we got the results we needed.