Eager Loading In Laravel
Lets start.
How to define Eager Loading In Laravel
1.Create laravel project and connect to database in .env file.
composer create-project laravel/laravel blog --prefer-dist
2.Create Model and Migrate it.
To implement Eager Loading in Laravel, we need models: Video,Comments
.
Now we need to create Video,Comments
models in fresh project so for that run below commands in comand prompt.
php artisan make:model Video -m
php artisan make:model Comments -m
Comments.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
public function Video()
{
return $this->belongsTo('App\Video');
}
}
Video.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Video extends Model
{
public function comments()
{
return $this->hasMany(Comment::class);
}
}
Fetch data from database using model name as below
$Videos = Video::all();
foreach ($Videos as $Video) {
echo $Video->name;
$comments = $Video->comments;
/* You can write loop again */
}
the above code how it works in backend and how much query being fire on database. so let's see below:
Now we execute same query in Mysql and we get ouput as below.
-- Select the Video i.e. Video::all();
SELECT * FROM Video;
-- Foreach of the Video, another query to select the comments
-- i.e. $Video->comments part of the loop
SELECT * FROM comments WHERE post_id = 1
SELECT * FROM comments WHERE post_id = 2
SELECT * FROM comments WHERE post_id = 3
Above Output each loop we execute another select query and getting all comments(In database each time data will be selecting). so when ever we are displaying 50 records then it's fire 50 query behind.
Now we see how can we get ouput in laravel
Display Video with Eager Loading:
$videos = Video::with('comments')->get();
foreach ($videos as $video) {
echo $video->name;
$comments = $video->comments;
/* You can write loop again */
}
Now you can see bellow how works with database query:
Queries with Eager Loading:
-- Select the Videos i.e. Video::all();
SELECT * FROM Videos;
-- Just One time get all comments with for that Videos
SELECT * FROM comments WHERE Video_id IN (1, 2, 3, 4, 5, ...);
Eager Loading Multiple Relationships
Sometimes you may need to eager load several different relationships in a single operation. To do so, just pass additional arguments to the with
method:
$Videos = Video::with(['comments', 'publisher'])->get();
Nested Eager Loading
To eager load nested relationships, you may use "dot" syntax. For example, let's eager load all of the book's authors and all of the author's personal contacts in one Eloquent statement:
$Videos = Video::with(['comments', 'comments.user'])->get();
Eager Loading With Select Specific Columns
$Video = Video::with(['comments:is,body'])->get();
Eager Loading With Count
$Video = Video::withCount('comments')->get();
Nested Eager Loading morphTo
Relationships
If you would like to eager load a morphTo
relationship, as well as nested relationships on the various entities that may be returned by that relationship, you may use the with
method in combination with the morphTo
relationship's morphWith
method. To help illustrate this method, let's consider the following model:
use Illuminate\Database\Eloquent\Model;
class ActivityFeed extends Model
{
/**
* Get the parent of the activity feed record.
*/
public function parentable()
{
return $this->morphTo();
}
}
In this example, let's assume Event
, Photo
, and Post
models may create ActivityFeed
models. Additionally, let's assume that Event
models belong to a Calendar
model, Photo
models are associated with Tag
models, and Post
models belong to an Author
model.
Using these model definitions and relationships, we may retrieve ActivityFeed
model instances and eager load all parentable
models and their respective nested relationships:
use Illuminate\Database\Eloquent\Relations\MorphTo;
$activities = ActivityFeed::query()
->with(['parentable' => function (MorphTo $morphTo) {
$morphTo->morphWith([
Event::class => ['calendar'],
Photo::class => ['tags'],
Post::class => ['author'],
]);
}])->get();