Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

lcopeland's avatar

Adding foreign keys with Migrations

I'm having trouble adding foreign keys to my database in laravel using migrations. Since migrations can't be reordered, I can't put them in my table creation migrations directly without needing to hack the times so that things get created in the right order. However, I'm not having any luck creating them after, either, and all my searches have turned up is people (somewhat unhelpfully) suggesting that I put them in the create methods.

Here's the table insert I'm trying to use:

    public function up()
{
        Schema::table('jobs', function($table)
        {
            $table->foreign('created_by_user_id')->references('id')->on('users');
            $table->foreign('customer_id')->references('id')->on('customers');
        });

My error is:

      [Illuminate\Database\QueryException]
      SQLSTATE[HY000]: General error: 1005 Can't create table 'cr_main.#sql-62af_
      1140' (errno: 150) (SQL: alter table `jobs` add constraint jobs_created_by_
      user_id_foreign foreign key (`created_by_user_id`) references `users` (`id`
      ))

Anyone got ideas?

0 likes
10 replies
helmerdavila's avatar
| table |
-------------
| user_id | int | unsigned
| customer_id | int | unsigned

After

$table->foreign('user_id')->references('id')->on('users');

Remember, first create the table and foreign field (ex. $table->integer('user_id')->unsigned()), and add the foreigns after.

2 likes
veve286's avatar

$table->integer('created_by_user_id')->unsigned(); $table->integer('customer_id')->unsigned(); $table->foreign('created_by_user_id')->references('id')->on('users'); $table->foreign('customer_id')->references('id')->on('customers');

I think u have to unsigned before referencing another table.

lcopeland's avatar

@helmerdavila, I understand that the tables need to be created first - they're already in the database as a result of older migrations. My question is whether it is possible to add foreign keys afterwards as a part of using migrations as version control, rather than inserting it in the original table declarations and having to hack the timestamps on the migrations so that everything executes in the correct order.

(If all else fails, I'll probably take this second option - I honestly would prefer if the migration system would just let us define our own execution order so we could use it as a schema definition rather than version control, which I think it does a pretty crappy job of, especially for cases like this.)

@veve286 updated all my tables to have unsigned fields, but I'm still getting the exact same error. I don't think that's it.

veve286's avatar

then can u upload all of the migration code ?

lcopeland's avatar

Figured it out, I hadn't declared some of my foreign key fields to be indexes, ie this:

  $table->integer('created_by_user_id')->unsigned()->index();

vs this:

  $table->integer('created_by_user_id')->unsigned();

I did end up having to manually edit the order of my migrations anyway, though, since the tables could no longer delete in the order they were declared due to the new constraints. I'm still not sure how you could do this task without needing to "hack" the version control system - re-declare all your tables, maybe?

1 like
blomdahldaniel's avatar

Still no one who has figured this out? This is really a major issue if one cannot ad the foreign keys afterwards...?!

envision's avatar

@blomdahldaniel I only skimmed this thread through but it seems he hadn't first declared those fields to be indexes... Apparently foreign key references fields that are indexed.

wa05's avatar
  • Solved erasing the data from the table that Im adding the foreign key (adding the foreign key to actual data with no value is an error... you are violating the foreign key before inserting it)...
  • Check that the foreign key and the id are both unsigned
  • Check that both related tables have InnoDB engine

Good luck!

lukeDev's avatar

So, I guess that I figured out, cause I have been through the same problem.

What I did: 1 - Create the migration file of each table without set foreign key 2 - Create a migration file specific for foreign keys.

That way you avoid the problem of order creation migration files when attempting to create index foreign key table that yet not exists in database

i.e:

public function up() { Schema::table('psicologos', function (Blueprint $table) { $table->foreign('user_id')->references('id')->on('users'); $table->foreign('cidade_id')->references('id')->on('cidades'); });

    Schema::table('schedules', function (Blueprint $table) {            
       $table->foreign('user_id')->references('id')->on('users');
    });

}

anonymouse703's avatar

If the tables are already used you can play it in the models you make a relationship of your table.

ex. in user model.

public function child_user(){
    return $this->hasMany('App\Customer','user_id','id');
}

then in customer model.

public function parent_user(){
    return $this->belongsTo('App\User','user_id','id');
}

Please or to participate in this conversation.