OHTA412

外部キー制約ありのカラムをマイグレーションで消す方法

Laravelで外部キー制約を付けているカラムをマイグレーションで消すとき、単純にdropColumnだけを行うと下記のようなエラーが返ってきます。

Illuminate\Database\QueryException  : SQLSTATE[42000]: Syntax error or access violation: 1091 Can't DROP FOREIGN KEY `user_id`; check that it exists (SQL: alter table `posts` drop foreign key `user_id`)

外部キー制約があるのでカラムを削除できないという趣旨のエラーです。この場合は外部キー制約も解除する必要があるので、その方法の紹介です。

マイグレーションファイルを作成

記事を管理しているpostsテーブルがあり、その記事を投稿したユーザーのIDも保存している場合の例です。

Schema::create('posts', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->string('title');
    $table->text('content');
    $table->unsignedBigInteger('user_id');
    $table->foreign('user_id')->references('id')->on('users');
    $table->timestamps();
});

user_idカラムはusersテーブルのIDに外部キー制約を設けていますが、このカラムを消す場合を考えます。

まず、下記コマンドでマイグレーションファイルを作成します。

php artisan make:migration drop_user_id_from_posts_table

作成されたマイグレーションファイルを下記コードのように変更します。

class DropUserIdFromPostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('posts', function (Blueprint $table) {
            // ここから追加
            $table->dropForeign('posts_user_id_foreign');
            $table->dropColumn('user_id');
            // ここまで追加
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('posts', function (Blueprint $table) {
            // ここから追加
            $table->unsignedBigInteger('user_id');
            $table->foreign('user_id')->references('id')->on('users');
            // ここまで追加
        });
    }
}

12行目でuser_idに設定されていた外部キー制約を解除しています。dropForeignメソッドを使い、引数に「テーブル名_カラム名_foreign」と記載します。

そして、13行目でuser_idカラムを削除しています。こうすることで外部キー制約があるカラムも削除することができます。

27~28行目は外部キー制約も含めたカラム登録の記述です。これにより元に戻すことができます。

マイグレートの実行

下記コマンドでマイグレートを実行して、カラムを削除します。

php artisan migrate