Laravel Many To Many Relationship: Complete Tutorial

Chimeremze Prevail Ejimadu
4 min readDec 15, 2022

--

Laravel Many To Many Relationship

Many to many relationships are vital in software development. In Laravel these relationships are defined as methods on your Eloquent model classes and they are very robust query builders. In this tutorial, we will see how to use many to many relationship in Laravel and how eloquent have made it very easy for us, with an example.

Many to many relationship is a tad more complicated than one to one and one to many relationships. An example of such a relationship is a User with may have multiple roles, where the Roles are also connected with multiple users, it can also be Stores in various Regions and these regions also have multiple stores, it can also be Products or Posts belonging to categories and these categories having many posts.

A many to many relationships involve three tables in its ecosystem. The two tables will be for the normal tables(with corresponding models) and the third table is what is known as a pivot table. A pivot table is an intermediate table that connects the two independent tables using their foreign keys.

1. Create a Laravel Project

The first step will be to create a Laravel project. If you already have a project, then you can skip this step

composer create-project laravel/laravel many_to_many

2. Create the models and migration files

The next step is to create the models and migration files for our project. Run the command below to create the Post and Category models and their migration files.

php artisan make:model Category -m
php artisan make:model Post -m
// In the Category migration
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
// In the Post migration
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('body');
$table->string('image')->nullable();
$table->timestamps();
});

3. Create a pivot table

Next we create a pivot table that will connect the two tables.

In Laravel, a pivot table is created by checking the alphabetical order of the two-parent tables using their singular names. For example, if we had parent table “a” and parent table “b”, then the pivot table would be “a_b”.

Using the same rule, I can create category_post, not post_category. Use the migration below:

php artisan make:migration create_category_post_table --create=category_post

Inside the file, add the columns

public function up()
{
Schema::create('category_post', function (Blueprint $table) {
$table->id();
$table->unsignedBiginteger('category_id');
$table->unsignedBiginteger('post_id');


$table->foreign('category_id')->references('id')
->on('categories')->onDelete('cascade');
$table->foreign('post_id')->references('id')
->on('posts')->onDelete('cascade');
});
}

You can now run migrations

php artisan migrate

4. Define many to many relationships

Remember that multiple categories belong to multiple Posts. So inside the Post.php file, we can define the belongsToMany() relationship.

 public function categories()
{
return $this->belongsToMany(Category::class);
}

Again, we do the same thing for the Category model. Inside the Category.php file, we can define the belongsToMany() relationship.

public function posts()
{
return $this->belongsToMany(Post::class);
}

5. How to use it?

We can now use this relationship anywhere in our controllers or services. Now let’s create a new Post and assign it to Categories with id 1, 2 and 4.

 public function store(Request $request)
{
$categories = [1, 2, 4];

$post = new Post();
$post->title = $request->title;
$post->body = $request->body;
$post->image = null;
$post->save();

$post->categories()->attach($categories);
//you can return json if it's an API,
return response()->json(['success' = true, 'post' => $post]);

// or you can return a view if it's a fullstack
//and pass $post via compact()
return view('view.name', compact('post'));
}

What exactly did we do here? First, we created a Post and saved it to the posts table, then we used the attach() method to assign those id to the posts thereby creating the relationship between the post and it’s categories.

Next, sync() method can be used to update many to many relationship attachments. You can make a PUT request to the update endpoint to achieve this.

 public function update(Request $request, $id)
{
$categories = [3, 6];
$post = Post::find($id);
$post->categories()->sync(categories);
}

Next, detach() method is used to delete the attachment of a record in many to many relationships.

public function destroy($id)
{
$post = Post::find($id);
$post->categories()->detach();

$post->delete();
}

Finally, how do we get this records? How do we retrieve this posts with their categories ?

We use the with() when calling the model.

public function index()
{
$posts = Post::with('categories')->get();

// you can return json if it's an API,
return response()->json(['posts' => $posts], 200);

// or you can return a view if it's a fullstack
// and pass $posts via compact()
return view('index', compact('posts'));
}

6. That’s it?

You have learnt how to use Laravel Many to many relationships. There are many way you can use this in building your next project. And if you want to know how to get each category inside your blade file, here’s one way to do it.

// show.blade.php

<h3>{{$post->title}}</h3>
<p>{{$post->body}}</p>
<ul>
@foreach($post->categories as $category)
<li>{{ $category->name }}</li>
@endforeach
</ul>

Stay tuned!!! I will be back with some more cool Laravel tutorials in the next article. I hope you liked the article. Don’t forget to follow me 😇 and give some clap 👏. And if you have any questions feel free to comment.

Thank you 🙏

Thanks a lot for reading till end 🙏 You can contact me in case if you need any assistance:
Email: prevailexcellent@gmail.com
Github: https://github.com/PrevailExcel
LinkedIn: https://www.linkedin.com/in/chimeremeze-prevail-ejimadu-3a3535219
Twitter: https://twitter.com/EjimaduPrevail

--

--

Chimeremze Prevail Ejimadu

Laravel Developer + Writer + Entrepreneur + Open source contributor + Founder + Open for projects & collaborations. Hit FOLLOW ⤵