How to add Foreign key in Migration – Laravel

In Laravel, migrations are a way to modify and manage the database schema of the application. 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 10 project.

How to add Foreign key in migration - Laravel


Table of Content

  1. Database Configuration
  2. Create Table and add Foreign Key Using Migration
  3. Create Models
  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 Using Migration

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.

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

States Table

  • 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');
    });
}

Cities Table

  • 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. Create Models

Create Countries, States, and Cities models.

Countries Model

  • 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'
      ];
}

States Model

  • 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'
      ];
}

Cities Model

  • Create Cities Model.
php artisan make:model Cities
  • 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

Adding a foreign key to the table using migration in Laravel is a straightforward process. By following these steps, you can easily define a foreign key constraint and maintain referential integrity between tables in your database.

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.

Follow the same steps if you are on Laravel 9 or 8.

View this official document to know more about foreign key implementation.

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