Understanding Eager Loading in Laravel Eloquent
This article explains Laravel Eloquent's eager loading techniques, demonstrating how to replace lazy-loaded N+1 queries with the with() method, preload multiple or nested relationships, select specific columns, apply constraints, and use lazy eager loading methods like load and loadMissing, all illustrated with PHP code examples.
Eager Loading
When you access a model relationship as a property, the related data is loaded lazily, meaning the query is executed only the first time the property is accessed. Laravel Eloquent can eager load relationships when querying the parent model, eliminating the N+1 query problem.
N+1 Query Example
Consider a Book model that belongs to an Author model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Book extends Model {
/**
* Get the author of the book
*/
public function author() {
return $this->belongsTo('App\Author');
}
}Fetching all books and then accessing each author inside a loop:
$books = App\Book::all();
foreach ($books as $book) {
echo $book->author->name;
}This loop runs one query to retrieve all books and then an additional query for each book to fetch its author. With 25 books, the database executes 26 queries.
Eager Loading with with
Using the with method reduces the queries to two:
$books = App\Book::with('author')->get();
foreach ($books as $book) {
echo $book->author->name;
}The generated SQL consists of a single query for books and another for authors with a WHERE id IN (...) clause.
Eager Loading Multiple Relationships
You can preload several relationships at once by passing an array to with :
$books = App\Book::with(['author', 'publisher'])->get();Nested Eager Loading
Use dot notation to eager load nested relationships, for example loading an author’s contacts together with the books:
$books = App\Book::with('author.contacts')->get();Selecting Specific Columns
If you only need certain columns from the related model, specify them in the relationship string:
$books = App\Book::with('author:id,name')->get();When selecting columns, always include the id column so the relationship can be matched.
Constrained Eager Loading
You can add additional query constraints to an eager load by providing a closure:
$users = App\User::with(['posts' => function($query) {
$query->where('title', 'like', '%first%');
}])->get();The above loads only posts whose title contains the word “first”. You can chain other query‑builder methods, such as ordering:
$users = App\User::with(['posts' => function($query) {
$query->orderBy('created_at', 'desc');
}])->get();Lazy Eager Loading
Sometimes you need to eager load relationships after the models have already been retrieved. The load method adds the specified relationships to the existing collection:
$books = App\Book::all();
if ($someCondition) {
$books->load('author', 'publisher');
}For conditional loading where a relationship should only be loaded if it hasn't been loaded yet, use loadMissing :
public function format(Book $book) {
$book->loadMissing('author');
return [
'name' => $book->name,
'author' => $book->author->name,
];
}This article demonstrates how Laravel’s eager loading features— with , load , and loadMissing —can dramatically reduce database queries and improve performance when working with related models.
Laravel Tech Community
Specializing in Laravel development, we continuously publish fresh content and grow alongside the elegant, stable Laravel framework.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.