user8867261
user8867261

Reputation:

Cannot create foreign key in laravel

I am trying to create a foreign key in my user_details table. I have 2 foreign keys in my user_details table, one is the user_id referencing to the user id in the main user table created by Sentinel. I also have a countries table where I want to set the country_of_origin field to the country numeric code from the countries table. but every time I execute my migration I get the following error

"Foreign key constraint is incorrectly formed"

Schema for my country table

 public function up()
{
    Schema::create('countries', function (Blueprint $table) {
        $table->collation = 'utf8_general_ci';
        $table->charset = 'utf8';
        $table->integer('id');
        $table->string('name');
        $table->string('alpha_2');
        $table->string('alpha_3');
        $table->timestamps();
        $table->engine = 'InnoDB';
    });
}

the id field is the ISO 3166-1 numeric country code, not an autoincrementing id for the row. Also, the data for this table is feed from a JSON file using a seeder.

Schema for my user details table

public function up()
{
    Schema::create('user_details', function (Blueprint $table) {
        $table->increments('id',true);
        $table->integer('user_id')->unsigned();
        $table->string('date_of_birth');
        $table->integer('country_of_origin')->unsigned();
        $table->integer('contact_number');
        $table->timestamps();
        $table->engine = 'InnoDB';
    });
    Schema::table('user_details', function($table) {
        $table->foreign('user_id')->references('id')->on('users');
        $table->foreign('country_of_origin')->references('id')->on('countries');
    });
}

The migration to create the country table is executed first before the the execution of the user_details migration.

if I remove $table->foreign('country_of_origin')->references('id')->on('countries'); I dont get any errors. I have also tried $table->integer('country_of_origin'); but i still get the same error.

Solution the issue was because of the name of the id field in the countries table but in reality, it wasn't an autoincrementing col rather had fixed value based on the seeded data.

I changed my Schema as follows Country Schema

 public function up()
{
    Schema::create('countries', function (Blueprint $table) {
        $table->collation = 'utf8_general_ci';
        $table->charset = 'utf8';
        $table->increments('id',true);
        $table->integer('num_id')->unique();
        $table->string('name');
        $table->string('alpha_2');
        $table->string('alpha_3');
        $table->timestamps();
        $table->engine = 'InnoDB';
    });
}

Added an extra field for the autoincrementing id and stored the SO 3166-1 numeric country code in the num_id field

in the User details table, just changed the following

 $table->foreign('country_of_origin')->references('num_id')->on('countries');

Upvotes: 1

Views: 136

Answers (2)

User123456
User123456

Reputation: 2738

public function up()
{
    Schema::create('countries', function (Blueprint $table) {
        $table->collation = 'utf8_general_ci';
        $table->charset = 'utf8';
        $table->integer('countryid')->unique();
        $table->string('name');
        $table->string('alpha_2');
        $table->string('alpha_3');
        $table->timestamps();
        $table->engine = 'InnoDB';
    });
}

Upvotes: 0

Onix
Onix

Reputation: 2179

id in countries table must be a primary key

Upvotes: 1

Related Questions