Just In Case. Laravel, create foreign key in migration

mitrallex
codeburst
Published in
3 min readAug 22, 2018

--

About Just In Case

While studying Laravel framework I faced with some not an obvious for me problems. And one day, when I realized that it might be helpful not only for me but for the other people to know about it, I decided to write down all the issues, that seems interesting for me.

For this purpose I will write series of articles with name “Just In Case”. So, information from these articles might not be very important but, you know, it’s just in case information.

Most information about Laravel framework you always can get from the official documentation. But here you can get little more details in some cases.

Introduction

In this article we will create foreign key constraint in migration in Laravel 5.6.

Act

Once I wanted to create messages table, and the first step that I made was creating migration for this table:

php artisan make:migration create_messages_table --create=messages

So that is what we get:

Schema::create('messages', function (Blueprint $table) {
$table->increments('id');
$table->string('email');
$table->text('text')->nullable();
$table->integer('type_id');
$table->integer('service_id')->nullable();
$table->boolean('status')->default(false);
$table->timestamps();
});

As you can see in this schema we have type_id and service_id fields. Obviously that it will be foreign keys. So let’s add foreign key constraints to this schema (Laravel documentation):

Schema::create('messages', function (Blueprint $table) {
$table->increments('id');
$table->string('email');
$table->text('text')->nullable();
$table->integer('type_id')->unsigned();
$table->integer('service_id')->unsigned()->nullable();
$table->boolean('status')->default(false);
$table->timestamps();

$table->foreign('type_id')
->references('id')
->on('message_types')
->onDelete('cascade');


$table->foreign('service_id')
->references('id')
->on('services')
->onDelete('cascade');
});

All right, now let’s create message_types table:

php artisan make:migration create_message_types_table --create=message_types

And services table:

php artisan make:migration create_services_table --create=services

There are no matters how schemas of these tables look like in this case. So now we have three migrations for tables messages, message_types and services. It’s great!

Now we can run our migrations:

php artisan migrate

Just In Case

But wait.. it’s not working! And here is the error:

errno: 150 "Foreign key constraint is incorrectly formed"

And the main reason is that Laravel created messages table and then tried to create foreign key constraint to table message_types that don’t exists yet.

If you look at your any migration file name, you can see that it starts from the date and time. For example create_users_table:

2014_10_12_000000_create_users_table

And Laravel migrations run earlier files at first. So in our case we just need to edit the file name of our create_messages_table migration as if we created this migration after create_message_types_table and create_services_table migrations.

Conclusion

The order of migration file is very important so my advice to you is always try to prepare you tables and relations between them on the paper at first. And only then generate migrations that you need in the right order. I think it will be nice to make it habit.

P.S. If you have any questions or suggestions write it on the comments. Thank you for the reading!

✉️ Subscribe to CodeBurst’s once-weekly Email Blast, 🐦 Follow CodeBurst on Twitter, view 🗺️ The 2018 Web Developer Roadmap, and 🕸️ Learn Full Stack Web Development.

--

--