25
Your First Eloquent Relationship in Laravel
Ep#24@Laracasts: Your First Eloquent Relationship
This post is a part of the Week X of 100DaysOfCode Laravel Challenge series.
Our next goal is to assign a category to our blog posts in our Blog Project. We show the category name on the blog archive and single post pages under post title.
We already have a posts
table for our posts. Now we will need another table for categories. We can make a relationship between the two tables so that each post entry has the category id it is assigned to.
So, we need to generate a migration and a model for the Category
. We can generate them in two separate commands
php artisan make:model Category
php artisan make:migration categories
or in one single command
php artisan make:model Category -m
where the -m
flag in the command is meant for a migration along with the model.
Now add the fields title
and slug
to the category schema in the categories migration. And add the category_id
as foreign key $table->foreignId("category_id");
to the posts
migration. Run your migrations php artisan migrate:fresh
. Boot up tinker php artisan tinker
and add some records to your categories
table.
use App\Models\Category;
$c = new Category;
$c->title = "Personal";
$c->slug = "personal";
$c->save();
Repeat the above commands for two other categories Work
and Hobbies
.
As we have assigned an empty array to the $guarded
property in our Post
model, we can create posts using Mass Assignment
.
use App\Models\Post;
$post = new Post;
$post->create(["title" => "Just a personal post", "slug" => "just-a-personal-post", "excerpt" => "lorem ipsum is simply....", "body" => "Lorem ipsum is simply a dummy text...", "category_id" => 1]);
Similarly, create some posts for the Work
and Hobbies
categories by assigning the respective category ids to them.
Now that we have assigned a category id to every post, can we access the category of a post like $post->category
? Nope, not yet, because we have not added Eloquent Relationship to our Post
model yet. The $post->category
will return null
instead.
In the Post
model, add a method category()
and return the appropriate relationship.
public function category() {
return $this->belongsTo(Category::class);
}
We used the belongsTo()
relation because in our case a category can have many posts but a post is assigned to exactly one category.
Now that we have added the Category
relation to our Post
model, it is time access the related category of a post. A potential confusion here could be trying to access the related model as a method $post->category()
, which will return the relation Illuminate\Database\Eloquent\Relations\BelongsTo {#4351}
instead of the model instance App\Models\Category
. So, access it as a property instead of a method.
use App\Models\Post;
$post = Post::first();
$post->category;
And it will return the category model instance as
>>> $post->category;
=> App\Models\Category {#3560
id: 1,
title: "Personal",
slug: "personal",
created_at: "2021-12-15 16:44:33",
updated_at: "2021-12-15 16:44:33",
}
>>>
Now you can access the related category title $post->category->title
which will return Personal
in the above case.
Update your blade templates to show a the associated category under each post title.
<p><a href="#">{{ $post->category->title }}</a></p>
Here we are introducing a problem called the N+1
problem which we will discuss in another episode. Now visit your blog listing page and you will see the category under post title as
To see all the changes made to the Blog Project, see the GitHub commit Ep#24 Your First Eloquent Relationship
.
25