How To Use One to Many Relationship in Laravel Application

In this article, we are going to create an example on how to use one to many relationship in Laravel Application.

Firstly, we need to know about one to many relationship, it’s mean one row in database table connect to many row in other tables.




We take an Blog as an example, a Category can have many Post and a Post belongs to a Category. You can see the example below.

To understand, how one to many relationship works in Laravel Application. We will give you an an example as step by step below.

Install Laravel

We create a project name onetomany , then you need to configure your .env file. Make sure our application can connect to database.

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

Create Model and Migration for table Category

To generate Category model and migration, we need to run command

php artisan make:model Category -m 

after we run the command line above. it will create model Category in your app folder name Category.php and the command also create migration in your folder database/migrations . Now Let’s see the content of the file




Category.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    //
}

Category Migration

<?php

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

class CreateCategoriesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('categories', function (Blueprint $table) {
            $table->id();
            $table->timestamps();
        });
    }

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




Create Model and Migration for Table Post

To create model and migration for Post, we need to run command

php artisan make:mode Post -m 

Above command will create

– Post model inside app folder called Post.php
– Post migration file inside database/migrations

Your model and migration file will look like

Post.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}




Post Migration

<?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->timestamps();
        });
    }

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

Adding Field into Category and Post migrations

we have added a few table fields for the category’s table.

Category migration

<?php

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

class CreateCategoriesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('categories', function (Blueprint $table) {
             $table->bigIncrements('id');
             $table->string('name');
             $table->text('description');
             $table->timestamps();
        });
    }

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

we have added a few table fields for the post’s table.

Post migration

<?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->bigIncrements('id');
            $table->integer('category_id')->unsigned();
            $table->foreign('category_id')
                  ->references('id')->on('categories')
                  ->onDelete('cascade');
            $table->string('title');
            $table->text('content');
            $table->timestamps();
        });
    }

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

we have added a few field on our posts migration. if you have notice category_id column is a foreign key on the category id column.




Now we can migrate our migration.

php artisan migrate 

How to define One to Many relationship Laravel

Now Let’s edit Category.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    public function posts() {

           return $this->hasMany(Post::class);
            
    }
}

As we define one to many between Category and Post model. It will return more than one of Post model. That’s why we define as posts in our Category.php Model.

How to define inverse One to Many relationship Laravel

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    public function category() {

         return $this->belongsTo(Category::class);
    }
}

In the above code, we define category() function. It will return the related post of the category.

Creating Database Seeder

In the article, we will use seed to insert data into database. We run command as below to create seeder

php artisan make:seeder PostsTableSeeder

php artisan make:seeder CategoriesTableSeeder

Then we need to edit the PotsTableSeeder.php and CategoriesTableSeeder.php inside database/seeder

<?php

use Illuminate\Database\Seeder;

class CategoriesTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        DB::table('categories')->insert([
            'name' => 'Laravel',
            'description' => 'Aldus PageMaker including versions of Lorem Ipsum.'
        ]);
        DB::table('categories')->insert([
            'name' => 'PHP',
            'description' => 'Aldus PageMaker including versions of Lorem Ipsum.'
        ]);

     
    }
}




<?php

use Illuminate\Database\Seeder;

class PostsTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        DB::table('posts')->insert([
            'category_id' => '1',
            'title' => '1. What is Lorem Ipsum?',
            'content' => 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.'
        ]);

        DB::table('posts')->insert([
             'category_id' => '1',
            'title' => '2. What is Lorem Ipsum?',
            'content' => 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.'
        ]);

        DB::table('posts')->insert([
            'category_id' => '2',
            'title' => '3. What is Lorem Ipsum?',
            'content' => 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.'
        ]);
    }
}

You need to add this two line of code into DatabaseSeeder.php inside folder database/migration/seeder

$this->call(CategoriesTableSeeder::class);
$this->call(PostsTableSeeder::class);

Then we can run command below to insert our data into database

php artisan db:seed

Create one to many relationship

We can create category or find one from our seeder. now I will use the existing data from our seeder which the category with id equal to 1. Then we can add a post into category. Let’s do as the below code.

$category = Category::find(1);

$post= new Post();
$post->title= 'New Post 4. What is Lorem Ipsum?';
$post->content = "Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.";

// Saving related model
$category->posts()->save($post);

So we will get one more data into post table.

Retrieving Related Data

You might want to get all post from first category. Then you can do as code below




$category = Category::find($id);   // you can pass $id or just assign the id value of category
$posts = $category->posts()->orderBy('name', 'asc')
                           ->get();

You will get all posts for a category which sorting by name in ascending order.

Dropping a one To many Relationship

As an example, if we can to delete all posts in specific category. We can do as the following.

$category = Category::find($id); // you can put 1 or 2 

$category->posts->delete();

Finally, we come to the end of the article. As I try to make the article short and simple. If you to see the videos. I will update the link here soon.


If you have any suggestion, Please leave a comment below

Thanks.

Recent graduated from Universitas Gadjah Mada, Yogyakarta, Indonesia and work as a Researcher at National Institute of Posts, Telecoms and ICT. Interested in Pattern Recognition and Artificial Intelligent.

Leave a reply:

Your email address will not be published.

Site Footer