Eager Loading in Foreach Loop: Boost Laravel Performance


Written By - Steve Alila
Advertisement

Eager loading is an optimization technique in Laravel to reduce the number of database queries. By default, when retrieving data with relationships in Laravel, it uses lazy loading, which can result in the N+1 query problem. However, using eager loading, we can solve this issue by retrieving all the related data in a single query.

In a foreach loop, we can use eager loading to retrieve all the related data at once, rather than querying the database each time for related data. This can lead to significant improvements in performance, particularly when working with large datasets.

In this approach, we can use the with() method to specify the related models we want to load. The with() method accepts an array of related models, and it loads all of them at once. By using this method, we can avoid multiple database queries and optimize the application's performance.

Laravel uses the with() function to achieve eager loading.

<code class="language-php">$children = <model>::with('<table column>')->get();

foreach ($children as $child) {
  // do something with each $child
}

In the foreach loop, we can now work with each child model and access the loaded relationship without generating additional queries. This technique can improve performance and optimize database queries when working with large datasets.

In this article, we will explore how to use eager loading in a foreach loop in Laravel, along with some best practices and tips for optimization.

 

Set up lab environment

First, create a new Laravel project by running the following command in your terminal:

laravel new eager_loading

Next, navigate into the project directory by running:

Advertisement
cd eager_loading

Install Laravel Breeze by running the following command:

composer require laravel/breeze --dev

Next, run the following command to install Breeze into your Laravel project:

php artisan breeze:install

Create a new MySQL database called eager_loading by running the following command:

mysql -u root
mysql> create database eager_loading;
mysql> exit;

Run the following command to create the necessary tables in your database:

php artisan migrate

Install the necessary NPM dependencies by running:

npm install

Compile your assets by running:

npm run dev

Start the Laravel development server by running:

php artisan serve

Create a new model for your database table by running the following command:

php artisan make:model <ModelName>

 

Example - Using eager loading in foreach loop Laravel

We will register users in a Laravel application. The users can create posts after logging into respective dashboards. Using eager loading, we will fetch the users and their posts.

We create a new Laravel application called eager_loading then install Breeze for user registration and logging. Next, we log in to a MySQL database and create a database. We then migrate the changes and start the development servers.

Eager Loading in Foreach Loop: Boost Laravel Performance

 

Register users

Now register three users.

  • Lorem lorem@ipsum.com
  • Mario mario@mario.com
  • Jane jane@doe.net

Then, create the posts with their (database) relationships with their (author) users. First, let's create a Post model with its migration and controller.

 

Migrate posts table

php artisan make:model Post -mcr

Next, create the relationships in the respective models.

// User
 public function posts() {
   return $this->hasMany(Post::class);
 }
​
//Post
public function user()
{
  return $this->belongsTo(User::class);
}

Eager Loading in Foreach Loop: Boost Laravel Performance

 

Now create the blueprint of each post.

 public function up(): void
 {
   Schema::create('posts', function (Blueprint $table) {
     $table->id();
     $table->unsignedBigInteger('user_id');
     $table->string('title');
     $table->text('body');
     $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
     $table->timestamps();
   });
 }

Then, migrate the changes.

php artisan migrate

Eager Loading in Foreach Loop: Boost Laravel Performance

 

Laravel Route and Controller for Post Creation and Storage

This code snippet includes the necessary routes and controller methods to create and store posts in Laravel. The create() method displays a form for the user to enter post details, and the store() method saves the post to the database with the currently authenticated user's ID.

// in routes/web.php

Route::get('/create', [PostController::class, 'create']);
Route::post('/store', [PostController::class, 'store']);
// in app/Http/Controllers/Post.php

<?php
​
namespace App\Http\Controllers;
​
use App\Models\Post;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
​
​
class PostController extends Controller
{
    public function create()
    {
        return view('create');
    }
​
    public function store(Request $request)
    {
​
        $blog = new Post();
​
        $blog->title = $request->title;
        $blog->body = $request->body;
        $blog->user_id = Auth::user()->id;
​
        $blog->save();
​
        return redirect('/');
    }
}
​

Layout

This is an example code for creating a layout view for a Laravel app with Vite. It includes links to CSS and JS files and a navigation bar with links to home, create, and dashboard pages. The layout view is used as a template for other views to extend and fill in the content.

<!-- resources/views/components/layout.blade.php -->
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
​
        <title>Laravel Demo Blog</title>
​
        <!-- Fonts -->
        <link rel="preconnect" href="https://fonts.bunny.net">
        <link href="https://fonts.bunny.net/css?family=figtree:400,600&display=swap" rel="stylesheet" />
​
        <!-- Styles -->
        @vite(['resources/css/app.css', 'resources/js/app.js'])
    </head>
    <body class="antialiased bg-slate-800 h-screen text-gray-200">
​
​
        <nav class="w-full flex justify-around items-center bg-slate-900 h-16 mb-10">
            <div>
                <a class="text-xl" href="{{ url('/') }}">Home</a>
            </div>
            <div></div>
            <ul class="flex space-x-6">
                
                @if (Route::has('login'))
                    @auth
                        <li>
                            <a href="{{ url('/create') }}">Create</a>
                        </li>
                        <li>
                            <a href="{{ url('/dashboard') }}">Dashboard</a>
                        </li>
                    @else
                    <li>
                        <a href="{{ route('login') }}">Login</a>
                    </li>
                    @if (Route::has('register'))
                    <li>
                        <a href="{{ route('register') }}">Register</a>
                    </li>
                    @endif
                    @endauth
                @endif
​
            </ul>
        </nav>
​
        {{ $slot }}
        
    </body>
</html>

Welcome

The code provided is an empty Blade view file located at resources/views/welcome.blade.php that extends the layout component by including the x-layout Blade directive. The layout component is defined in the resources/views/components/layout.blade.php file and includes the basic HTML structure for the application's layout, such as the head section with the necessary meta tags and stylesheets, and the body section with the navigation menu and a slot to include the content specific to the current view.

<!-- resources/views/welcome.blade.php -->
<x-layout>
    
</x-layout>

Create

The form submits to the 'store' route using the POST method.

Inside the form, we have used the CSRF token using the '@csrf' Blade directive to protect against cross-site request forgery attacks. We have also used some Tailwind CSS classes to style the form elements.

<!-- resources/views/create.blade.php -->
<x-layout>
<form action="{{ url('store') }}" method="post" class="w-2/4 mx-auto">
    @csrf 
    <div class="mb-4">
        <label for="title" class="block mb-2">Title:</label>
        <input type="text" name="title" class="w-full bg-gray-100 text-gray-700 p-2 rounded focus:outline-none sm:w-4/5">
    </div>
    <div class="w-full mb-4">
        <label for="body" class="block mb-2">Body:</label>
        <textarea name="body" id="body" rows="7" class="w-full bg-gray-100 text-gray-700 p-2 rounded focus:outline-none sm:w-4/5"></textarea>
    </div>
    <div class="mb-4">
        <button class="bg-cyan-800 hover:bg-cyan-900 rounded px-8 py-2 ">Store</button>
    </div>
</form>
</x-layout>

Now that a user can log in a create a post, let me show you how to load the users with their posts.

 

Eager loading users and posts

Route::get('/users', function () {
    $users = User::with('posts')->get();
    foreach ($users as $user) {
        echo $user->name. '<br>';
        echo '******<br>';
        foreach ($user->posts as $post) {
            echo $post->title. '<br>';
        }
        echo '............................<br><br>';
    }
});

On hitting the /users route, Laravel eagerly loads users with their posts. Using foreach loop, we loop through each user and print their name and posts.

how to use eager loading=

 

Conclusion

In this tutorial, we learned how to use eager loading in Laravel's foreach loop to improve application performance. Eager loading is a technique for loading related data together with the primary model, which avoids the N+1 query problem that occurs when we use the traditional method of loading related data inside a loop.

We started by defining eager loading and discussing the benefits of using it, including reducing the number of queries, improving application performance, and avoiding potential performance issues. Then we looked at a code example where eager loading is used to load posts along with their respective users, and we looped through each user and their posts. We also provided catchy title suggestions for articles related to the topic.

Next, you created a Laravel blog from scratch, registered, logged in, and authenticated each user before enabling them to create some posts. Lastly, you loaded all users and posts using Laravel eager loading.

 

Can't find what you're searching for? Let us assist you.

Enter your query below, and we'll provide instant results tailored to your needs.

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can either use the comments section or contact me form.

Thank You for your support!!

Leave a Comment