Nested Eager Loading in Laravel: Optimize Your Database Queries

Understanding Nested Eager Loading in Laravel Eloquent

Laravel’s Eloquent ORM simplifies database interactions, and one of its standout features is eager loading. This technique allows you to load related models alongside the main model, significantly reducing the number of queries executed. When your relationships become complex, nested eager loading becomes essential. In this article, we will dive into nested eager loading, its benefits, and practical examples using different models, including how to structure your data into clean nested arrays.

What is Nested Eager Loading?

Nested eager loading allows you to load relationships of a model’s relationships in a single query. For example, if you have a Project model that has an Owner, and each Owner has Contacts and a Company, nested eager loading can retrieve all of this related data efficiently.

Why Use Nested Eager Loading?

  • Performance: Minimizes database queries.
  • Clarity: Keeps your code clean and understandable.
  • Efficiency: Loads all necessary data in one go.

Implementing Nested Eager Loading

To implement nested eager loading in Laravel, you can use the with method when querying your models. Here’s how it works:

Example Scenario

Let’s consider a scenario with the following models:

  • Project: Represents a project.
  • Owner: Represents the owner of the project.
  • Contact: Represents contact information for the owner.
  • Company: Represents the company associated with the owner.

Defining Relationships

First, ensure your relationships are set up correctly in your models:

class Project extends Model {
    // A project belongs to an owner
    public function owner() {
        return $this->belongsTo(Owner::class);
    }
}

class Owner extends Model {
    // An owner can have many contacts
    public function contacts() {
        return $this->hasMany(Contact::class);
    }

    // An owner belongs to a company
    public function company() {
        return $this->belongsTo(Company::class);
    }
}

class Contact extends Model {
    // A contact belongs to an owner
    public function owner() {
        return $this->belongsTo(Owner::class);
    }
}

class Company extends Model {
    // A company can have many owners
    public function owners() {
        return $this->hasMany(Owner::class);
    }
}

Querying with Nested Eager Loading

To retrieve all projects along with their owners, owners’ contacts, and companies, you can use:

$projects = Project::with([
    'owner' => [
        'contacts',  // Load the owner's contacts
        'company',   // Load the company associated with the owner
    ],
])->get();

This query loads all projects and their associated owners, contacts, and companies in one database call.

Displaying Nested Data

You can display this data in a view as follows:

@foreach ($projects as $project)
    <h2>{{ $project->title }}</h2>
    <p>Owner: {{ $project->owner->name }}</p>
    
    <h4>Contacts:</h4>
    <ul>
        @foreach ($project->owner->contacts as $contact)
            <li>{{ $contact->email }}</li>  <!-- Display each contact's email -->
        @endforeach
    </ul>
    
    <p>Company: {{ $project->owner->company->name }}</p> <!-- Display the owner's company name -->
@endforeach

Advanced Usage

You can also apply conditions when eager loading nested relationships. For instance, if you want to load only active contacts for each owner:

$projects = Project::with(['owner.contacts' => function ($query) {
    $query->where('active', true);  // Only load active contacts
}, 'owner.company'])->get();

This ensures that only active contacts are retrieved alongside their respective owners and companies.

Conclusion

Nested eager loading is a powerful feature in Laravel that enhances performance and keeps your codebase clean. By understanding how to implement it effectively, you can optimize your database interactions and improve overall application efficiency.

Keep helping and happy 😄 coding

Vishnu Damwala
Vishnu Damwala

A web geek, an industry experienced web developer & tutor/instructor residing in India 🇮🇳