Laravel 8 One to Many Eloquent Relationship Tutorial

Reading Time: 11 minutes
10,756 Views

Laravel eloquent relationship is a very important feature which connects one or more tables in a chain. This is the substitute of joins in laravel.

Laravel provides these following relationships –

Eloquent relationships are defined as methods on your Eloquent model classes. Inside this article we will see the concept of laravel 8 One to Many Eloquent relationship as well as we will implement inverse of one to many relationship i.e belongs to.

This article will give you the detailed concept of about implementation of one to many relationship in laravel.

For this tutorial we will consider a posts table and a comments table. This means a single post can have multiple comments.

Let’s get started.


Laravel Installation

We will create laravel project using composer. So, please make sure your system should have composer installed. If not, may be this article will help you to Install composer in system.

Here is the command to create a laravel project-

composer create-project --prefer-dist laravel/laravel blog

To start the development server of Laravel –

php artisan serve

URL: http://127.0.0.1:8000

Assuming laravel already installed inside your system.


Create Database & Connect

To create a database, either we can create via Manual tool of PhpMyadmin or by means of a mysql command.

CREATE DATABASE laravel_app;

To connect database with application, Open .env file from application root. Search for DB_ and update your details.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_app
DB_USERNAME=root
DB_PASSWORD=root

Create Migrations

We need to create two migration files.

  • Migration file for Posts table
  • Migration file for Comments table

Open project into terminal and run these migration command.

$ php artisan make:migration CreatePostsTable

$ php artisan make:migration CreateCommentsTable

It will create two files 2021_04_01_162614_create_posts_table.php & 2021_04_01_162630_create_comments_table.php at /database/migrations folder.

Open 2021_04_01_162614_create_posts_table.php and write this complete code into it.

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string("title");
            $table->text("description")->nullable();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('posts');
    }
}

Open 2021_04_01_162630_create_comments_table.php and write this code into it.

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateCommentsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('comments', function (Blueprint $table) {
            $table->id();
            $table->unsignedInteger('post_id');
            $table->string("comment");
            $table->timestamps();
            $table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('comments');
    }
}

Run Migrations

Next, we need to create tables inside database.

$ php artisan migrate

This command will create tables inside database.


Create Model

Next, we need to create two models. Back to terminal and run these artisan commands.

$ php artisan make:model Post

$ php artisan make:model Comment

This command will create two files Post.php & Comment.php at /app/Models folder.

Open Post.php and write this complete code into it.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Models\Comment;

class Post extends Model
{
    use HasFactory;

    protected $fillable = ["title", "description"];

    /**
     * Get the comments for the blog post.
     */
    public function comments()
    {
        return $this->hasMany(Comment::class);
    }
}

$this->hasMany(Comment::class); It is creating one to many relationship.

Open Comment.php and write this complete code into it.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Models\Post;

class Comment extends Model
{
    use HasFactory;

    protected $fillable = ["post_id", "comment"];

    /**
     * Get the post that owns the comment.
     */
    public function post()
    {
        return $this->belongsTo(Post::class);
    }
}

$this->belongsTo(Post::class); It is creating inverse of one to many relationship.


Sample Data Insertion

Open mysql and run these queries to insert dummy data into posts and comments table.

Data for Posts Table

--
-- Dumping data for table `posts`
--

INSERT INTO `posts` (`id`, `title`, `description`, `created_at`, `updated_at`) VALUES
(1, 'Odie Robel', 'Quae eveniet hic qui ut molestias dignissimos. Corporis dolore dolor eius illum quia. Qui eaque vero vel sunt suscipit cupiditate. Aspernatur dolor numquam ut beatae et architecto repellat.', '2021-04-01 11:07:38', '2021-04-01 11:07:38'),
(2, 'Earl Weissnat', 'Quaerat quasi libero et error commodi. Nihil consectetur suscipit deleniti corporis aut et est modi. Nostrum nostrum voluptatibus qui quaerat inventore qui.', '2021-04-01 11:07:38', '2021-04-01 11:07:38'),
(3, 'Ms. Samanta Haley MD', 'Sit ut architecto sit quis. Non ipsa sed distinctio ullam vel. Minus aut recusandae sed rem ipsam. Quasi doloribus non exercitationem architecto aut.', '2021-04-01 11:07:38', '2021-04-01 11:07:38'),
(4, 'Mr. Bertha Jakubowski III', 'Nemo recusandae voluptas quae quisquam dolores quia. Quo totam nostrum ut autem facere.', '2021-04-01 11:07:38', '2021-04-01 11:07:38'),
(5, 'Dr. Casimir D\'Amore DVM', 'Sed natus voluptatibus non blanditiis porro. Totam veniam officia doloremque qui accusamus magnam neque. Et fugit nulla expedita vel nesciunt optio aliquid.', '2021-04-01 11:07:38', '2021-04-01 11:07:38'),
(6, 'Ms. Letitia Koch Sr.', 'Aut ut quidem nemo qui pariatur amet itaque. Minima dicta enim quia voluptatibus. Nobis itaque tempore qui. Aperiam ea quam necessitatibus maxime.', '2021-04-01 11:07:38', '2021-04-01 11:07:38'),
(7, 'Sophie Rempel', 'Consequatur sed harum ut similique. Voluptate nisi nihil illum eum dolore. Et qui doloremque facere officia similique. Rerum quia aut et nulla esse quia.', '2021-04-01 11:07:39', '2021-04-01 11:07:39'),
(8, 'Dr. Virginia Gislason', 'Et placeat aut consequatur. Est dolorum et ut non minus. Ut ab et alias earum et modi. Pariatur rerum nisi veritatis id dolores.', '2021-04-01 11:07:39', '2021-04-01 11:07:39'),
(9, 'Miss Caitlyn Heller', 'Est debitis vitae qui a a. Commodi in ut corrupti nobis repellendus libero eos impedit. Libero est officia et. Voluptate vel quos vel autem nihil dolor.', '2021-04-01 11:07:39', '2021-04-01 11:07:39'),
(10, 'Mozell Moore', 'Eos enim molestias voluptate quo ipsa. Autem et voluptas quaerat est maxime. Magnam corrupti et omnis similique assumenda tempora harum. Est recusandae magni nulla eos corporis officiis alias.', '2021-04-01 11:07:39', '2021-04-01 11:07:39');

Data for Comments Table

--
-- Dumping data for table `comments`
--

INSERT INTO `comments` (`id`, `post_id`, `comment`, `created_at`, `updated_at`) VALUES
(1, 1, 'Exercitationem ea possimus saepe. Odit quas ut ea vitae officiis. Consequatur vel beatae aut qui voluptatum at. Magnam natus eaque sunt rerum repellat.', '2021-04-01 11:07:39', '2021-04-01 11:07:39'),
(2, 2, 'Voluptatem repellendus alias hic tempora corrupti dolor sit expedita. Qui quasi pariatur sint consequuntur tenetur minus debitis.', '2021-04-01 11:07:39', '2021-04-01 11:07:39'),
(3, 1, 'Aut consequatur ipsum nisi quo et ea deserunt. Rem qui ipsa sed nisi. Similique vel voluptatem omnis fuga reprehenderit et nisi. Voluptate voluptatem et sapiente est sed ipsum similique.', '2021-04-01 11:07:39', '2021-04-01 11:07:39'),
(4, 4, 'Odit hic aut ut molestiae quod. Tempora harum est ut sit ratione et. Quam vitae explicabo fugit.', '2021-04-01 11:07:39', '2021-04-01 11:07:39'),
(5, 3, 'Cum corporis assumenda adipisci rem deleniti. Ut sint voluptate et qui saepe fugiat in. Laborum nemo doloribus odio dolorem.', '2021-04-01 11:07:39', '2021-04-01 11:07:39'),
(6, 3, 'Nihil explicabo nisi eveniet aut provident. Odio molestias dolores sint quia omnis dolore harum est. Nisi ipsa ex laborum error est. Repellat possimus eveniet vel et.', '2021-04-01 11:07:39', '2021-04-01 11:07:39'),
(7, 7, 'Autem id omnis quos. Et eos et eos expedita ad libero. Quos quia labore quibusdam maxime cupiditate.', '2021-04-01 11:07:39', '2021-04-01 11:07:39'),
(8, 2, 'Alias placeat expedita in laudantium. Quos ea qui voluptatibus rem. Temporibus dignissimos in in.', '2021-04-01 11:07:39', '2021-04-01 11:07:39'),
(9, 8, 'Ut dolorem quasi hic cumque. Dolorum eum porro reiciendis et neque. Quis praesentium quis iusto dignissimos laudantium illum enim. Sit eos nulla qui.', '2021-04-01 11:07:39', '2021-04-01 11:07:39'),
(10, 8, 'Incidunt ab explicabo veritatis et. Perspiciatis eum incidunt officia aut autem impedit vitae. Qui aliquid repudiandae qui asperiores ea et ipsa est.', '2021-04-01 11:07:39', '2021-04-01 11:07:39');

Calling Methods at Controller

Open any controller say SiteController.php file, we have created two methods in which we used model methods as a property.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Post;
use App\Models\Comment;

class SiteController extends Controller
{
    public function getComments($post_id)
    {
        // Passing post id into find()
        return Post::find($post_id)->comments;
    }

    public function getPost($comment_id)
    {
        // Passing comment id into find()
        return Comment::find($comment_id)->post;
    }
}
  • Post::find($post_id)->comments; It will find comments detail values by post id. One to Many
  • Comment::find($comment_id)->post; It will find post detail by comment id. Inverse of One to Many / Belongs To

Create Routes

Open web.php from /routes folder and add these routes into it.

# Add this to header
use App\Http\Controllers\SiteController;

Route::get('get-comments/{id}', [SiteController::class, 'getComments']);
Route::get('get-post/{id}', [SiteController::class, 'getPost']);

Application Testing

Run this command into project terminal to start development server,

php artisan serve

Get Comments – http://127.0.0.1:8000/get-comments/1

Get Post detail– http://127.0.0.1:8000/get-post/1

We hope this article helped you to learn about Laravel 8 One to Many Eloquent Relationship Tutorial in a very detailed way.

If you liked this article, then please subscribe to our YouTube Channel for PHP & it’s framework, WordPress, Node Js video tutorials. You can also find us on Twitter and Facebook.