16
loading...
This website collects cookies to deliver better user experience
N+1
problem on the blog overview page by Eager loading the Category
and User
models with the Post
model as part of the query.routes/web.php
Route::get('/', function () {
return view('posts', [
'posts' => Post::latest()->with("category", "author")->get()
]);
});
N+1
problem is again there on the Author and Category pages.routes/web.php
Route::get('/categories/{category:slug}', function (Category $category) {
return view('posts', [
'posts' => $category->posts
]);
});
Route::get('/authors/{author:username}', function (User $author) {
return view('posts', [
'posts' => $author->posts
]);
});
load()
method with relation names passed as parameters.routes/web.php
Route::get('/categories/{category:slug}', function (Category $category) {
return view('posts', [
'posts' => $category->posts->load("author", "category")
]);
});
Route::get('/authors/{author:username}', function (User $author) {
return view('posts', [
'posts' => $author->posts->load("author", "category")
]);
});
12
vs 4
. The number of queries reduced from 12 to 4, a big improvement.$with
property to the model.App\Models\Post
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
protected $guarded = [];
protected $with = ['category', 'author'];
public function getRouteKeyName()
{
return 'slug';
}
public function category() {
return $this->belongsTo(Category::class);
}
public function author() {
return $this->belongsTo(User::class, "user_id");
}
}
load()
methods from the route definitions.route/web.php
Route::get('/categories/{category:slug}', function (Category $category) {
return view('posts', [
'posts' => $category->posts
]);
});
Route::get('/authors/{author:username}', function (User $author) {
return view('posts', [
'posts' => $author->posts
]);
});
N+1
problem still doesn't exist.Post
will be retrieved, the related User
and Category
models will be loaded by default. Let's test in tinker.php artisan tinker
>>> Post::first();
=> App\Models\Post {#4287
id: 1,
user_id: 1,
category_id: 1,
title: "Dignissimos animi aut consequatur aspernatur in libero labore.",
slug: "similique-repellendus-id-est-et-illum",
excerpt: "Vitae voluptatibus aut et id blanditiis.",
body: "Ut dolor sit quia minima.",
published_at: null,
created_at: "2021-12-25 14:18:42",
updated_at: "2021-12-25 14:18:42",
category: App\Models\Category {#4249
id: 1,
title: "magnam",
slug: "dolor",
created_at: "2021-12-25 14:18:42",
updated_at: "2021-12-25 14:18:42",
},
author: App\Models\User {#4511
id: 1,
name: "John Doe",
username: "JohnDoe",
email: "[email protected]",
email_verified_at: "2021-12-25 14:18:42",
#password: "$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi"
,
#remember_token: "qFYOFvkIyS",
created_at: "2021-12-25 14:18:42",
updated_at: "2021-12-25 14:18:42",
},
}
>>>
Category
and User
models loaded by default with the Post
model. If you would like to selectively remove one of these loaded related models, you can pass its name to the without()
as:>>> Post::without("category")->first();
=> App\Models\Post {#4515
id: 1,
user_id: 1,
category_id: 1,
title: "Dignissimos animi aut consequatur aspernatur in libero labore.",
slug: "similique-repellendus-id-est-et-illum",
excerpt: "Vitae voluptatibus aut et id blanditiis.",
body: "Ut dolor sit quia minima.",
published_at: null,
created_at: "2021-12-25 14:18:42",
updated_at: "2021-12-25 14:18:42",
author: App\Models\User {#4514
id: 1,
name: "John Doe",
username: "JohnDoe",
email: "[email protected]",
email_verified_at: "2021-12-25 14:18:42",
#password: "$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi"
,
#remember_token: "qFYOFvkIyS",
created_at: "2021-12-25 14:18:42",
updated_at: "2021-12-25 14:18:42",
},
}
>>>
Category
model is included but the User
is not. Want to exclude the User
too?>>> Post::without("category", "author")->first();
=> App\Models\Post {#3564
id: 1,
user_id: 1,
category_id: 1,
title: "Dignissimos animi aut consequatur aspernatur in libero labore.",
slug: "similique-repellendus-id-est-et-illum",
excerpt: "Vitae voluptatibus aut et id blanditiis.",
body: "Ut dolor sit quia minima.",
published_at: null,
created_at: "2021-12-25 14:18:42",
updated_at: "2021-12-25 14:18:42",
}
>>>
load()
the relations based on some condition.$with
property as explained above.