Eloquent ORM One-to-Many Relationships MySQL — Laravel

Cerwyn Cahyono
4 min readApr 19, 2020

--

Photo by Pixabay from Pexels

As you know, in relationships between tables in the database, we usually have 3 types of relationships. These relationships are called one-to-one, one-to-many, and many-to-many relationships.

I have made an article describing the one-to-one relationship, now I will explain the one-to-many relationship. As usual, I will make a small demo to explain what happened to this relationship in the API development. Of course, what I’m about to show is the logic to do some CRUD operations. I have prepared the github project at the bottom of this article and these are the outlines:

Content Overview

  • One to Many Relationship
  • Laravel Preparation
  • Migration
  • Eloquent ORM
  • Controller & Routing

One-to-Many Relationship

Let’s start! In this project, I created 2 new tables with the relationship below.

Image 1. ER Diagram One-to-Many

We will create 2 tables, the articles and comments tables because usually these two objects have one-to-many relationship. An article can have many comments right? But a comment only belongs to one article. That’s why this relationship named one-to-many. Let’s setup the project

Laravel Preparation

I use composer here, so at the command prompt type

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

Of course you can create your own project name, but in this example I use one-to-many. If you use XAMPP, don’t forget to start it and modify the database name inside the .env file.

Migration

Now we need 2 migrations, let’s setup them.

php artisan make:migration create_articles_table
php artisan make:migratino create_comments_table

There will be 2 new files in the database/migrations folder. First let’s configure the create_articles_table.php first.

databases/migrations/create_articles_table.php

Then the next one, open create_comments_table.php

databases/migrations/create_comments_table.php

As you can see in the comments table, I set the foreign key for article_id column. This column will refer to the id column on articles table. Don’t forget, if one article is deleted, then all the comments related to that article must be deleted as well. So that’s why I use onCascade(‘delete’) function to represent that behavior.

One more thing, i think it is interesting if each article has a best_comment_id column to represent the best comment of each article. Of course, you don’t need to set the best_comment_id column to be a foreign key, just set it as the bigInteger type to save the comment id and it is a nullable column.

Done! Don’t forget to start your XAMPP (if you use that) and configure your database name in the .env file of your project. Then, run the migration!

php artisan migrate

You know what, the migration function (and the Factory/Faker) has so many useful operations and I think it’s interesting if I make one article to cover this migration commands.

Eloquent ORM

Next thing to do, let’s make 2 models. One for articles and another for comments.

php artisan make:model Article
php artisan make:model Comment

We must configure the relationship between the two tables in this models. This relation has slight differences from a one-to-one relationship, but of course, Laravel makes everything easier with Eloquent ORM.

The models will appear in app/Article.php and app/Comment.php. Let’s open the article model

app/Article.php

Then the next one, open comment model

app/Comment.php

All right! Let’s cover the article model first. In the article model, you will see a new function called comments(). The function is explicitly returning with hasMany(‘app\Comment’) function. Laravel will automatically look for a comment table that has the value of the article_id column the same as the current article id. If in the comments table you don’t have any article_id column, but you specify another name (for example another_column_name) , then you can modify the hasMany function become like this: hasMany(‘app\Comment’,’another_column_name’).

But, again, if you don’t specify the second parameter, Laravel will automatically lookup the article_id column in comments table. The convention is always a singular table name with the ending _id.

What about the comments table? Because a comment always has one relation with the articles table, then we can use the belongsTo(‘app/Article’) method. Laravel will automatically lookup an article that has the same id as in the article_id column. Again, if you don’t use the article_id column name, then you must specify it in the second parameter of belongsTo() function.

Controller & Routing

We need two controllers now, so let’s create them

php artisan make:controller ArticleController
php artisan make:controller CommentController

We will find the new controllers inside app/Http/Controllers. Let setup the ArticleController.php first

app/Http/Controllers/ArticleController.php

Then let’s setup the CommentController.php

app/Http/Controllers/CommentController.php

Whoa there are so many functions here.These functions give examples of how logic works with this relations. The most important thing is when a user save a new comment. First, let’s look at the CommentController inside the store() function. First, I use some validations here when a user insert a new comment, but that’s optional. Then, we create the new comment object and we save the object with calling the article object. If you notice, I never explicitly set a value for the article_id column, but Laravel will automatically save the value for the article_id column when we call $article->comments()->save($comment) function.

The behavior is same when we are reading the comments data. From the ArticleController, we just need call $article->comments function to show all the comments related to that article. In a reverse, from the CommentController, we just call $comment->article function to find out what article that has this comment. Impressive! Behind the scene, of course Laravel do the rest!

Last step, let’s setup the routing.

routes/api.php

It’s done! I hope this article can be your reference for how we can handle a one-to-many relationship with Laravel. Thank you for reading this!

Github:
https://github.com/Cerwyn/laravel-one-to-many

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

--

--

Cerwyn Cahyono

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