My migration fails when I try to execute php artisan migrate
or php artisan migrate:refresh
with this error:
errno: 150 "Foreign key constraint is incorrectly formed"
Code
Users Table (migrated successfully)
public function up() { Schema::create('users', function (Blueprint $table) { $table->integer('id',)->primary(); $table->string('name', 255); $table->string('surname', 255); $table->string('email', 255)->unique(); $table->string('password', 255); $table->string('profile_image', 255); $table->string('profile_cover', 255); $table->rememberToken(); $table->char('token', 255)->unique()->nullable()->default(null); $table->enum('role', ['user', 'driver', ',merchant', 'storemanager', 'storeoperator', 'company', 'employee']); $table->dateTime('created'); $table->dateTime('updated'); }); }
Address Table (fails with error)
public function up() { Schema::create('address', function (Blueprint $table) { $table->integer('id')->primary(); $table->string('address1'); $table->string('address2'); $table->string('city'); $table->integer('country')->unsigned(); $table->decimal('latitude'); $table->decimal('longitude'); $table->string('instructions'); $table->integer('default'); $table->integer('user')->unsigned(); $table->dateTime('created'); $table->dateTime('updated'); $table->foreign('country')->references('id')->on('country')->onUpdate('cascade'); $table->foreign('user')->references('id')->on('users')->onUpdate('cascade'); }); }
Advertisement
Answer
One of the reasons to work with a framework such as Laravel is syntactic sugar. By following their conventions, you write less code and have to think about fewer of the “nuts and bolts” of your application.
You are doing the opposite of this, and are already seeing the consequences. You will experience so much more pain once you try setting up models and their relationships. Instead you should be using a migration that looks like this:
<?php use IlluminateDatabaseMigrationsMigration; use IlluminateDatabaseSchemaBlueprint; use IlluminateSupportFacadesSchema; class CreateAddressesTable extends Migration { public function up() { // table names are plural of the object name Schema::create('addresses', function (Blueprint $table) { // automatically create an incrementing bigint column called 'id' $table->id(); // name foreign ID columns correctly to save yourself trouble later $table->foreignId('country_id')->constrained(); $table->foreignId('user_id')->constrained(); // specify lengths for your varchar columns $table->string('address1', 100); $table->string('address2', 100); $table->string('city', 100); $table->decimal('latitude'); $table->decimal('longitude'); $table->string('instructions', 100); $table->integer('default'); // why would you define your own timestamp columns with non-standard names? $table->timestamps(); }); } }
And the users
table; you’d want to update its migration similarly.
<?php use IlluminateDatabaseMigrationsMigration; use IlluminateDatabaseSchemaBlueprint; use IlluminateSupportFacadesSchema; class CreateUsersTable extends Migration { public function up() { Schema::create('users', function (Blueprint $table) { $table->id(); // DO NOT use an enum column; create another table called roles instead $table->foreignId('role_id')->constrained(); $table->string('name', 100); $table->string('surname', 100); $table->string('email', 100)->unique(); $table->string('password', 255); $table->string('profile_image', 255); $table->string('profile_cover', 255); $table->rememberToken(); // $table->char('token', 255)->unique()->nullable()->default(null); $table->timestamps(); }); }