(先に)まとめ

⭐️ 外部キー制約の drop と同時に、制約対象の key を変更や削除する場合はスキーマを分ける必要がある
✏️ 外部キー制約を drop するときは1つのスキーマでまとめて実行できる

テーブル条件

  • テーブル名:animals
  • カラム名:kindId
  • 外部キー設定先テーブル名:animal_kinds
  • 外部キー設定先カラム名:id

作成した migration ファイル

<?php

public function up()
{
    Schema::table('animals', function (Blueprint $table) {
        $table->unsignedBigInteger('kind')->change();
        $table->foreign('kind')->references('id')->on('animal_kinds');
    });
}

public function down()
{
    Schema::table('animals', function (Blueprint $table) {
        $table->dropForeign('animals_kind_foreign');
        $table->bigInteger('kindId')->change();
    })
}

migration を実行し、rollback した際にエラー発生

  [Illuminate\Database\QueryException]                                                                                   
  SQLSTATE[HY000]: General error: 1832 Cannot change column 'kind': used in a foreign key constraint 'animal_kinds' (SQL: ALTER TABLE animal_kinds CHANGE kind kind BIGINT NOT NULL COMMENT '-')                                                 
                                                                                                                         
  [Doctrine\DBAL\Driver\PDOException]                                                                                    
  SQLSTATE[HY000]: General error: 1832 Cannot change column 'kind': used in a foreign key constraint 'animal_kinds'                                                                                        
  [PDOException]                                                                                                         
  SQLSTATE[HY000]: General error: 1832 Cannot change column 'kind': used in a foreign key constraint 'animal_kinds'

down() を以下のように書き換えることで成功

  • 外部キー制約の drop と、カラム変更のスキーマを分割
<?php

public function down()
{
    Schema::table('animals', function (Blueprint $table) {
        $table->dropForeign('animals_kind_foreign');
    });
    Schema::table('animals', function (Blueprint $table) {
        $table->bigInteger('kindId')->change();
    });
}