laravel

Laravel8で外部キー制約をマイグレーションで追加する方法【デフォルトの型に注意】

鍵

 

あなた
Laravel8で外部キー制約をマイグレーションで設定するにはどうしたらいいですか?

 

今回はこんな疑問に答えていきます。

 

【前提】

・laravel8系

・マイグレーションの仕組み自体は把握している(把握できていない方はLaravel8でマイグレーションを行う方法【カラム追加/削除・カラム変更・インデックス追加/削除など】を読んで学習しておきましょう)

 

Laravel8で外部キー制約をマイグレーションで追加する方法

 

結論から話すと、Laravel8で外部キー制約をマイグレーションで設定する方法は以下の2つになります。

 

・パターン1:foreign、references、onメソッドを使う

・パターン2:foreignId、constrainedメソッドを使う

 

パターン1は旧式で、パターン2はLaravel7から使えるようになったようですね。

それぞれについて解説します。

 

パターン①

 

パターン1の場合の記述は以下のようになります。

 

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

Schema::table('posts', function (Blueprint $table) {
    $table->unsignedBigInteger('user_id');
    //user_idはuserテーブルのidを外部キーとする
    $table->foreign('user_id')->references('id')->on('users');
});

 

パターン1は少し冗長ではありますね。

そこでパターン2が出てきました。

 

パターン②

 

パターン2では以下のように記述できます。

 

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

Schema::table('posts', function (Blueprint $table) {
    //user_idはuserテーブルのidを外部キーとする
    $table->foreignId('user_id')->constrained();
});

 

1行で完結して、見やすくなりました。

laravel7以降使えるようです。

 

「Referencing column '〇_id' and referenced column 'id' in foreign key constraint '〇〇' are incompatible.」というエラーが出る場合

 

ちなみになのですが、「Referencing column '○_id' and referenced column 'id' in foreign key constraint '〇〇' are incompatible.」のようなエラーが出るときがあります。

このエラーが出るときは「外部キーを設定しようとしたカラムの型が、間違っている」ということが考えられます。

 

例えば、usersテーブルのidはtinyintなのに、postsテーブルの user_idでbigintを指定してしまったとかです。

 

注意:デフォルトのforeignIdはbigIntegerを指定する

 

注意点なのですが、foreignIdメソッドを使った場合はデフォルトでbigIntegerが指定されます。

呼び出し先のメソッドは以下のようになっています。

 

public function foreignId($column)
    {
        return $this->addColumnDefinition(new ForeignIdColumnDefinition($this, [
            'type' => 'bigInteger',
            'name' => $column,
            'autoIncrement' => false,
            'unsigned' => true,
        ]));
    }

 

つまり、外部キーとしてbigInteger以外の型を指定したい場合はforeignIdを使わないほうがいいということです。

 

Laravel8で型指定で外部キー制約を付けたい場合

 

Laravel8で型指定で外部キー制約を付けたい場合は、foreignIdを使わない書き方をしましょう。

2つほど例を書いておきます。

 

以前の書き方

 

旧式の書き方であれば、「カラム作成」「外部キー設定」が別に書かれていました。

なので、柔軟に型を変更可能です。

 

//型を自在に変更できる
$table->unsignedTinyInteger('user_id');
//型指定後に外部キー設定
$table->foreign('user_id')->references('id')->on('users');

 

特に問題なければ上記やり方がスマートです。

 

DBファサードを使ってSQL直書き

 

DBファサードを使ってSQLを直書きして、外部キーを設定する方法もあります。

コードは次のような感じになります。

 

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;

class AddForeignKeyToMessages extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('messages', function (Blueprint $table) {
            DB::statement('ALTER TABLE `laravel`.`messages`
ADD INDEX `messages_user_id_foreign_idx` (`user_id` ASC) VISIBLE;');
            DB::statement('ALTER TABLE `laravel`.`messages`
ADD CONSTRAINT `messages_user_id_foreign`
  FOREIGN KEY (`user_id`)
  REFERENCES `laravel`.`users` (`id`)
  ON DELETE RESTRICT
  ON UPDATE RESTRICT;');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('messages', function (Blueprint $table) {
            DB::statement('ALTER TABLE `laravel`.`messages`
DROP FOREIGN KEY `messages_user_id_foreign`;');
            DB::statement('ALTER TABLE `laravel`.`messages`
DROP INDEX `messages_user_id_foreign`;');
        });
    }
}

 

ただ、さすがに冗長すぎるので、優先して使うことはないかなと。

SQL直書きは、便利ですが、見やすさを失うこともあるので、適時に使っていきましょう。

今回は以上です。

 

参考:公式ドキュメント(マイグレーション)

 

Laravelの記事はこちらから見ることができます。

 

プログラミングスクールに関する情報

【無料あり】プログラミングスクールおすすめランキング【WEBエンジニアになりたい方向け】と書かれた画像
【無料あり】プログラミングスクールおすすめランキング【WEBエンジニアになりたい方向け】

  あなたプログラミングスクールに通いたいけどたくさんありすぎてどこがいいのかわかりません。   最近はエンジニアブームということもありプログラミングスクールが増えました。 一方でたくさんありすぎてど ...

続きを見る

返金保証ありのプログラミングスクールランキング【エンジニアが選びました】と表示されたパソコンの画面
【転職保証つき】返金保証ありのプログラミングスクールランキング【エンジニアが選びました】

  あなた返金保証がついているオススメのプログラミングスクールってありますか?   結論から話すと、返金保証つきのプログラミングスクールランキングは次の通りです。   1位:DMMWEBキャンプ  【 ...

続きを見る

wordpress
【無料あり】WEB制作を学べるオンラインスクールランキング【副業で稼ぎたい方向け】

  あなたWeb制作の副業で稼ぎたいけど、どのスクールで学ぶのが良いの? スクール選びで失敗はしたくないです。   ↑このような疑問や不安を解決するべく、現役のWebエンジニアがWEB制作を学べるスク ...

続きを見る

フリーランス
無料あり:フリーランスを目指せるプログラミングスクールランキング【体験をもとに徹底分析しました】

  あなたフリーランスエンジニアを目指すことができるプログラミングスクールってありますか?   最近では、高年収や働きやすさの魅力からフリーランスエンジニアを目指す方も増えてきました。 結論から話すと ...

続きを見る

WEB系自社開発企業にいけるプログラミングスクールランキング【現役エンジニアおすすめ】と書かれた画像
WEB系自社開発企業にいけるプログラミングスクールランキング【現役エンジニアおすすめ】

  あなたWEB系の自社開発企業に就職したいです。 オススメのスクールを教えて下さい。   結論から話すと、WEB系自社開発に行きやすいスクールのランキングは以下の通り。   第1位:テックアカデミー ...

続きを見る

-laravel

S