Eloquent ORM Many-to-Many Relationships MySQL — Laravel

Cerwyn Cahyono
4 min readApr 26, 2020
Photo by Pixabay from Pexels

I have two articles that explain the one-to-one and one-to-many relationships in Laravel, so in this article I’ll explain about many-to-many relationships. As you know, we can find so many cases where we can implement this relationship such as articles with their categories/tags, users with their roles/profiles, and so on. So, this relationship is more common to be used in real projects but is more complex than the other two relationships because it requires a pivot table.

As always, I have prepared the Github and postman API collection below and here’s the outline of this article:

Content Overview:

  • Many-to-Many ER Diagram
  • Database Migration
  • Eloquent ORM Model
  • Controller & Routing

Many-to-Many ER Diagram

In this article, we’ll use this ER Diagram below to demonstrate the many-to-many relationship:

Image 1. Many-to-Many ER Diagram

Based on our diagram, we have 3 tables now. So we have the users and events tables and store its relationship in a pivot table named event_user. The event_user table will store the data when a user book some events so, a user can have multiple events to book and vice versa, an event can be booked my multiple users.

Database Migration

First thing first, let’s start by creating a project using composer.

composer create-project --prefer-dist laravel/laravel many-to-many

Once complete, you will find the migration tables inside database/migrations/ folder. There, you’ll find a create_user_table.php and let’s use this for our users table. So we will create another two tables.

php artisan make:migration create_events_table
php artisan make:migration create_event_user_table

If you’re wondering why the table event_user name is weird, it’s because I used the Laravel naming convention when creating a pivot table name. The naming convention for a pivot table is: put together the two table names in a singular form in alphabetical order. This naming convention will make it easier for us to set up the model later.

Let’s open the database/migrations/create_events_table.php.

database/migrations/create_events_table.php

Then database/migrations/create_event_user_table.php.

database/migrations/create_event_user_table.php

Nothing special here except, the primary key for event_user table. I use $table->primary([‘user_id’,’event_id’]) it means that, the combination between user_id and event_id must be unique. It doesn’t make sense if a user can book same multiple events right? So that’s why I use that combination for the primary key.

Don’t forget to set up your database name in .env file of your project, and run the migration

php artisan migrate

Eloquent ORM Model

So now, we have 3 new tables appear in our database, but we only need 2 models in this project. In this case, we don’t need to create a model for event_user table because Laravel will store the many-to-many relationships automatically in our pivot table. Let’s create the Event model

php artisan make:model Event

Then open the app/Event model.

app/Event.php

For reading and storing the relationship between users table, we use belongsToMany() function without specifying the pivot table name because we are following the naming convention for pivot table. If you have a pivot table without following the naming convention, then you must specify the pivot table name inside the second argument of belogsToMany(). So the function will become like, belongsToMany(‘App\User’,’anotherpivottable’). But again, in this case we don’t need to specify the second argument because our pivot table name has following the naming convention.

app\User.php

There is nothing special in the User model, we just added a new function called events() at the bottom.

Controller & Routing

So let’s setup the controllers by creating them first.

php artisan make:controller UserController -r
php artisan make:controller EventController -r
php artisan make:controller UserEventController -r
php artisan make:controller EventUserController -r

Now we have 4 controllers inside app/Http/Controllers. Let’s open the UserController.

app/Http/Controllers/UserController.php

As you can see, we have a function named book_event() there. When we are storing the relationship, it’s very easy with Eloquent ORM Laravel. We can just call $user->events()->save($event, array(‘note’ => $note)) function without specifying anything about our pivot table. In addition, I add another column named note in the pivot table and that’s the way on how storing this note column into our pivot table. Super easy right?

Then let’s configure the EventController.

app/Http/Controllers/EventController.php

For the Event controller, there’s nothing special here. We only use index, store, and show methods. Let’s continue with UserEventController.

app/Http/Controllers/UserEventController.php

We only have 1 function here that’s the index. It’s super easy when we are accessing the events for a specific user with $user->events function. Of course, Laravel will do the rest. Next the EventUserController,

app/Http/Controllers/EventUserController.php

Again, we only need the index function here for showing all users that booked a specific event. We only need to call $event->users function to get all of the users. Last thing to do, let’s set up the API routing.

routes/api.php

In this route, we use Route::resource() function so that Laravel will automatically create the routes for us. If you want to know what routes that we have, just type this in the command prompt:

php artisan route:list

Then it’s done. We have successfully build the many-to-many relationship with Laravel. It’s super easy right? I hope this article can be a good reference for you when building this type of relationship. Thank you

Github:
https://github.com/Cerwyn/Laravel-Many-to-Many

Postman API Collection: https://www.getpostman.com/collections/a2fb13620a2532e0f298

--

--

Cerwyn Cahyono

PHP/Backend Engineer at Undercurrent Capital Pte Ltd — Data Science Enthusiast