How to add Foreign key in Migration – Laravel

A foreign key is a field that is used to establish the relationship between two tables via the primary key (You can also use a non-primary field but not recommended).

In this tutorial, I show how you can add a foreign key constraint while creating a table using migration in the Laravel 9 project.

How to add Foreign key in migration - Laravel


Contents

  1. Database Configuration
  2. Create Table and add Foreign Key
  3. Model
  4. Conclusion

1. Database Configuration

Open .env file.

Specify the host, database name, username, and password.

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

2. Create Table and add Foreign Key

Create countries, states, and cities tables using migration.

I am adding foreign key on states and cities tables.

  • states table is linked to countries table, and
  • cities table is linked to states table.

  • Create Countries table –
php artisan make:migration create_countries_table
  • Now, navigate to database/migrations/ folder from the project root.
  • Find a PHP file that ends with create_countries_table and open it.
  • Define the table structure in the up() method.
public function up()
{
    Schema::create('countries', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->timestamps();
    });
}

  • Create States table –
php artisan make:migration create_states_table
  • Similarly, find a PHP file that ends with create_states_table in database/migrations/ folder and open it.
  • Define the table structure in the up() method.

Adding foreign key –

  • I am adding a foreign key to country_id field.
  • Set datatype of this field to UNSIGNED BIGINT – $table->unsignedBigInteger('country_id');. Datatype must be UNSIGNED and same as the parent table linking field datatype.
  • Here, countries table id field has biginteger datatype.
  • Add foreign key –
$table->foreign('country_id')
     ->references('id')->on('countries')->onDelete('cascade');

Values – 

  • foreign() – Pass field name which you want to foreign key constraint.
  • references() – Pass linking table field name.
  • on() – Linking table name.
  • onDelete(‘cascade’) – Enable deletion of attached data.
public function up()
{
    Schema::create('states', function (Blueprint $table) {
         $table->id();
         $table->unsignedBigInteger('country_id');
         $table->string('name');
         $table->timestamps();
         $table->foreign('country_id')
              ->references('id')->on('countries')->onDelete('cascade');
    });
}

  • Create Cities table –
php artisan make:migration create_cities_table
  • Similarly, find a PHP file that ends with create_cities_table in database/migrations/ folder and open it.
  • Define the table structure in the up() method.

Adding foreign key –

  • I am adding a foreign key to states_id field.
  • Set datatype of this field to UNSIGNED BIGINT – $table->unsignedBigInteger('state_id');. Datatype must be UNSIGNED and same as the parent table linking field datatype.
  • Here, states table id field has biginteger datatype.
  • Add foreign key –
$table->foreign('state_id')
     ->references('id')->on('states')->onDelete('cascade');

Values – 

  • foreign() – Pass field name which you want to foreign key constraint.
  • references() – Pass linking table field name.
  • on() – Linking table name.
  • onDelete(‘cascade’) – Enable deletion of attached data.
public function up()
{
    Schema::create('cities', function (Blueprint $table) {
         $table->id(); 
         $table->unsignedBigInteger('state_id');
         $table->string('name');
         $table->foreign('state_id')
                  ->references('id')->on('states')->onDelete('cascade');
         $table->timestamps();
    });
}

  • Run the migration to create tables –
php artisan migrate

3. Model

Create Countries, States, and Cities models.

  • Create Countries Model.
php artisan make:model Countries
  • Open app/Models/Countries.php file.
  • Specify mass assignable Model attributes – name using the $fillable property.

Completed Code

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Countries extends Model
{
      use HasFactory;

      protected $fillable = [
          'name'
      ];
}

  • Create States Model.
php artisan make:model States
  • Open app/Models/States.php file.
  • Specify mass assignable Model attributes – country_id, and name using the $fillable property.

Completed Code

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class States extends Model
{
      use HasFactory;

      protected $fillable = [
           'country_id','name'
      ];
}

  • Create Cities Model.
php artisan make:modelCities
  • Open app/Models/Cities.php file.
  • Specify mass assignable Model attributes – state_id, and name using the $fillable property.

Completed Code

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Cities extends Model
{
      use HasFactory;

      protected $fillable = [
         'state_id','name'
      ];
}

4. Conclusion

In the example, I added a single foreign key to a table but you can add more than one foreign key to a table by following the same steps.

You can learn more about it from here.

If you found this tutorial helpful then don't forget to share.