Laravelのマイグレーションで外部キーが通らない場合の確認事項

Laravelのマイグレーションで外部キーを含めたテーブルを作成した際に詰まったのでメモ。

Laravelの仕様とカラムの型を理解すれば、外部キー設定のマイグレーションを失敗することは大幅に軽減すると思うので、今回は気をつける点を解説していきます。

 

【環境】

Laravel5.6

MySQL5.7

 

外部キーと参照先idのカラム型が違う問題

これは、外部キーを設定するカラムを参照先のカラムの型と同じにすればOK。

一般的に、Laravelのプライマリキーの設定は以下のincrementsメソッドがデフォルトであるが、これは暗黙的にunsigned int型のカラムを生成する。

$table->increments('id');

 

なので、外部キーの設定を以下のどちらかにしてあげればOK。

$table->integer('user_id')->unsigned()

$table->unsignedInteger('user_id');

※ 両方同じくunsigned int型の定義方法であるので、お好きな方をどうぞ。

 

 

マイグレーションファイルの実行順で失敗する問題

これは、外部キー参照先のマイグレーションファイルが実行されてない状態で、外部キー設定したマイグレーションファイルが実行されると、参照するテーブルがないとエラーを返されます。

 

マイグレーションファイルが実行される順番は?

ファイルの作成した順に実行されるようです。これは、Laravelの仕様になっています。

 

例えば、以下のように、blogsテーブルの外部キー参照先にusersテーブルを設定したい場合は、usersマイグレーションファイルの作成日2018_7_10より後にblogsのマイグレーションファイル作成すればOK。

2018_7_10_131643_create_users_table.php

public function up()

{

  Schema::create('users', function (Blueprint $table) {

      $table->increments('id');

      $table->string('name');

      $table->text('comment');

      $table->softDeletes();

      $table->timestamps();

  });

}

 

2018_07_11_131526_create_blogs_table.php

public function up()

{

  Schema::create('blogs', function (Blueprint $table) {

      $table->increments('id');

      $table->unsignedInteger('user_id');

      $table->string('title');

      $table->text('body');

      $table->softDeletes();

      $table->timestamps();

      $table

          ->foreign('user_id')

          ->references('id')

          ->on('users')

          ->onDelete('cascade');

  });

}

 

これは、Laravelの気の利いた仕様に我々がついていけずに発生するエラーですね。

 

 

まとめ

今回は、備忘録も兼ねて投稿させていただきました。この記事が皆さんの活動を手助けになれば幸いでございます。