お久しぶりです、やすのりです!
今日はLaravelでテーブル作成時に詰まったので備忘録も兼ねて記事を書いていきたいと思います。
結論
外部キーと参照元カラムの設定は同じにしよう!!
何があったのか?
業務上でLaravelアプリを使用していますが、その中で新しいテーブルを3つ作って全部リレーションさせて、尚且つその内の2つは『外部キーの参照元を主キー以外に設定』する仕様になっていました。
1つ目のテーブルを作成するのは難なくできましたが...2つ目のテーブルを作成する時にエラーが出まくりました!
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (S
QL: alter table `test2` add constraint `test2_test1_id_foreign` foreign key (`test1_id`) references `test1` (`test1_id`))
※カラム名は仮称にしてあります。
とSQLの『test2テーブルのtest1_idは外部キー設定が出来ませんよ!!』というエラーが出てきました...
このエラーでよく見かける解決ほうに『主キーの型と外部キーの型が間違っている』というものがありました。
そして実際のコードを見てみましょう。
public function up()
{
Schema::create('test1', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->integer('test1_id')->unsigned()->unique();
$table->timestamps();
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
});
}
public function up()
{
Schema::create('test2', function (Blueprint $table) {
$table->increments('id');
$table->integer('test1_id');
$table->integer('test2')->unique();
$table->timestamps();
$table->foreign('test1_id')
->references('test1_id')
->on('test1');
});
}
はい、この時点で分かる人には分かりますね。
そう、『test1テーブルのtest1_idに'符号なし'を意味する'unsigned'を設定しているのに、test2テーブルの外部キーである'test1_id'には設定していない』からでした!
今思えば単純なことだし、初歩的なことなんですけど...
エラーが発生している時は『主キーの型と外部キーの型が間違っている』という部分に引っ張られて『え〜?主キーである'id'と'test1_id'は同じinteger型なんだけどなぁ』とか思っていました...
いや、普通はそれでいいんだけど、今回は主キー以外を外部キーにしてるから『外部キーと参照元のカラムが同じ型かどうか?』を確認しないとダメでした!
いやぁ、意外と初歩的なことって間違えちゃいますね!!
ってことで型が間違ってないか分かりやすくするためにさっきまで使用していた『unsigned』という記述ではなくて、そもそもの型の記述を『unsignedInteger』に変更しちゃいました!
public function up()
{
Schema::create('test1', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('user_id');
$table->unsignedInteger('test1_id')->unique();
$table->timestamps();
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
});
}
public function up()
{
Schema::create('test2', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('test1_id');
$table->unsignedInteger('test2')->unique();
$table->timestamps();
$table->foreign('test1_id')
->references('test1_id')
->on('test1');
});
}
これならパッと見で違ってたらわかるでしょう!!
感想
みなさん、初心は忘れないようにしましょう...
お兄さんとの約束ですよ!!