Adding Foreign Key References Using a Laravel Migration

  • March 31, 2016

Welcome to the incredibly popular Easy Laravel 5 companion blog. To celebrate the new edition's release (updated for Laravel 5.5!) use the discount code easteregg to receive 20% off the book or book/video package! » Buy the book

Laravel really excels at facilitating deft management and navigation of table relations, but you'll need to understand how to properly configure these relationships before taking advantage of them.

Consider the TODOParrot example application's relationship between a TODO list and assigned category. Each list belongs to a category, whereas each category can have many lists. This means the todolists table will contain a foreign key named category_id (although it is possible to override the foreign key field name if you desire). In this tutorial I'll show you the steps necessary to configure this belongs to / has many relationship using migrations and model relations. Let's kick things off by creating the migration:

$ php artisan make:migration add_category_id_to_todolists \
> --table=todolists

You're free to name the migration anything you please; I try to be as explicit as possible so as to easily find the migration later should it require further modification. After executing this migration you'll find a file named 2016_03_30_152547_add_category_id_to_todolists.php (the timestamp prefix will of course be different) in your project's database/migrations directory. Open this file and you'll find the usual up() and down() methods. Modify the up() method to look like this:

public function up()
{
    Schema::table('todolists', function(Blueprint $table)
    {
        $table->integer('category_id')->unsigned()->after('id');
        $table->foreign('category_id')->references('id')->on('categories');
    });
}

Only two lines comprise the up() method, yet both are probably rather cryptic to the newcomer. The first line creates an column named category_id of type integer (unsigned), placing it directly after the id column. You don't have to be bothered with placing the column in a specific location; I just like to place my primary key and foreign keys at the "top" of the table.

The second line identifies this newly created column as being a foreign key, and specifies that it refers to the categories table's id column.

That wasn't so bad, was it? Next up is the down() method:

public function down()
{
    Schema::table('todolists', function(Blueprint $table)
    {

        $table->dropForeign('todolists_category_id_foreign');
        $table->dropColumn('category_id');

    });
}

These two lines aren't perhaps so mysterious; should we need to roll back the migration, the foreign key reference and column itself will be removed (dropped).

After saving the changes, run the migration per usual:

$ php artisan migrate
Migrated: 2016_03_30_152547_add_category_id_to_todolists.php

With the table schema updated, you'll next need to update the Category and Todolist model. Starting with Category.php, add the following method:

public function lists()
{
    return $this->hasMany('App\Todolist');
}

Save the changes, and open up the Todolist model (Todolist.php), adding the following method:

public function Category()
{
    return $this->belongsTo('App\Category');
}

With these changes in place you're ready to begin using your new relation! If you'd like to learn much more about Laravel migrations and relations, be sure to check out my bestselling book, "Easy Laravel 5".