Laravel migrations nice way of disabling foreign key checks Laravel migrations nice way of disabling foreign key checks laravel laravel

Laravel migrations nice way of disabling foreign key checks


I had a similar task at hand when Lumen / Laravel started using Passport and I had to ditch the previous oauth server implementation from lucadegasperi/oauth2-server-laravel.

I finally managed to get things going by creating 2 migrations, where the first one clears foreign keys and the second one actually deletes the tables.

I had to use dates before the migrations of Laravel's Passport (2016-06-01) so they will be executed before those.

2016_05_31_000000_clear_old_oauth_relations.php

//...class ClearOldOauthRelations extends Migration{    public function up()    {        Schema::disableForeignKeyConstraints();        // drop foreign keys        Schema::table('oauth_access_tokens', function (BluePrint $table) {            $table->dropForeign('oauth_access_tokens_session_id_foreign');        });        //...        Schema::enableForeignKeyConstraints();    }    //...}

And in the second file2016_05_31_000001_clear_old_oauth.php

//...public function up(){    Schema::disableForeignKeyConstraints();    Schema::drop('oauth_access_tokens');    //...    Schema::enableForeignKeyConstraints();}//...


I got this done by extracting the foreign key logic into a separate migration file. This helped me to:

  • Disable the foreign key constraints.
  • Securely drop the database, if it exists.

In code:

//file: 2017_06_19_230601_fk_postuser_table.phppublic function down(){        Schema::disableForeignKeyConstraints();        Schema::dropIfExists('post_user');}


Another important aspect to remember is to drop the foreignKey FIRST, then the column. Dropping the column first throws the error:

Cannot drop index 'tableName_columnName_foreign': needed in a foreign key constraint

The proper order matters:

    public function down()    {        Schema::table('tableName', function (Blueprint $table) {            $table->dropForeign(['columnName']); // fk first            $table->dropColumn('columnName'); // then column        });    }