59
loading...
This website collects cookies to deliver better user experience
Post
and User
models. So, we are all set to view all posts by an author too. All we need now is to add the corresponding route to our app.routes/web.php
Route::get('/authors/{author}', function (User $author) {
return view('posts', [
'posts' => $author->posts
]);
});
author
in this case. You should also remember that the wildcard by default looks for the id
attribute of the model. So we should now get all posts by the user with id
equal to 1 using the URL http://127.0.0.1:8000/authors/1
(local).posts.blade.php
post.blade.php
<p>
By <a href="/authors/{{ $post->user->id}}">
{{ $post->user->name }}
</a> in <a href="/categories/{{ $post->category->slug }}">
{{ $post->category->title }}
</a>
</p>
Post
model as user
. This is a contradiction between what we speak and what we code. So, we should rename our relation from user
to author
in the Post
model, and update the views accordingly.\App\Models\Post
public function author() {
return $this->belongsTo(User::class);
}
posts.blade.php
post.blade.php
<p>
By <a href="/authors/{{ $post->author->id}}">
{{ $post->author->name }}
</a> in <a href="/categories/{{ $post->category->slug }}">
{{ $post->category->title }}
</a>
</p>
author_id
as the foreign key of the relation which is not present in the users
table. The solution is to specify the foreign key name as the second optional parameter of the belongsTo()
relationship.\App\Models\Post
public function author() {
return $this->belongsTo(User::class, "user_id");
}
http://127.0.0.1:8000/authors/1
is neither looking very prettier nor is it very useful. We may want to manually write the name or username of an author in the URL and filter posts by that author. So, what User
attribute should we replace the id
with? The full name doesn't look very suitable attribute. We can update it to username
instead. So update the route definition to specify the username
in the route wildcard.routes/web.php
Route::get('/authors/{author:username}', function (User $author) {
return view('posts', [
'posts' => $author->posts
]);
});
username
key in our users
table. So, add the line $table->string('username')->unique();
to your users
table migration file.database/migrations/2014_10_12_000000_create_users_table.php
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('username')->unique();
...
});
'username' => $this->faker->unique()->username()
to the UserFactory
.database/factories/UserFactory.php
public function definition()
{
return [
'name' => $this->faker->name(),
'username' => $this->faker->unique()->username(),
...
];
}
php artisan migrate:fresh --seed
username
column is added to your users
table and you can filter posts by username as http://127.0.0.1:8000/authors/JohnDoe
. Update views for blog overview and individual blog post pages to replace the id
with username
in the link.posts.blade.php
post.blade.php
<p>
By <a href="/authors/{{ $post->author->username}}">
{{ $post->author->name }}
</a> in <a href="/categories/{{ $post->category->slug }}">
{{ $post->category->title }}
</a>
</p>
routes/web.php
Route::get('/', function () {
return view('posts', [
'posts' => Post::with("category")->get()
]);
});
latest()
method on the Post
model to fetch posts in the latest-first order.routes/web.php
Route::get('/', function () {
return view('posts', [
'posts' => Post::latest()->with("category")->get()
]);
});
\App\Models\Post::factory()->create();
to verify it appears on the top.N+1
problem when we referenced the related Category
model on the blog overview page. Now we are again in the N+1
problem as we showed authors on the blog overview page.routes/web.php
Route::get('/', function () {
return view('posts', [
'posts' => Post::latest()->with("category", "author")->get()
]);
});
"category"
parameter in the with()
method, now we added the "author"
too to eager load it with the posts. Visit blog overview page http://127.0.0.1:8000/
again and notice the number of queries in the Clockwork tab this time.