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.

Table of Content
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.
statestable is linked tocountriestable, andcitiestable is linked tostatestable.
Countries Table
- Create
Countriestable –
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_tableand 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
Statestable –
php artisan make:migration create_states_table
- Similarly, find a PHP file that ends with
create_states_tableindatabase/migrations/folder and open it. - Define the table structure in the
up()method.
Adding foreign key –
- I am adding a foreign key to
country_idfield. - Set datatype of this field to UNSIGNED BIGINT –
$table->unsignedBigInteger('country_id');. Datatype must beUNSIGNEDand same as the parent table linking field datatype. - Here,
countriestableidfield hasbigintegerdatatype. - 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
Citiestable –
php artisan make:migration create_cities_table
- Similarly, find a PHP file that ends with
create_cities_tableindatabase/migrations/folder and open it. - Define the table structure in the
up()method.
Adding foreign key –
- I am adding a foreign key to
states_idfield. - Set datatype of this field to UNSIGNED BIGINT –
$table->unsignedBigInteger('state_id');. Datatype must beUNSIGNEDand same as the parent table linking field datatype. - Here,
statestableidfield hasbigintegerdatatype. - 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
CountriesModel.
php artisan make:model Countries
- Open
app/Models/Countries.phpfile. - Specify mass assignable Model attributes –
nameusing the$fillableproperty.
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
StatesModel.
php artisan make:model States
- Open
app/Models/States.phpfile. - Specify mass assignable Model attributes –
country_id, andnameusing the$fillableproperty.
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
CitiesModel.
php artisan make:model Cities
- Open
app/Models/Cities.phpfile. - Specify mass assignable Model attributes –
state_id, andnameusing the$fillableproperty.
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.