【Laravel】既存のテーブルに外部キーを設定、解除するマイグレーションを作る

Laravelでテーブルに変更を加える場合、基本的にマイグレーションで指示を書きます。
マイグレーションを書く時は、必ず立ち上げ時に起動するup関数と、ロールバックやリセットで実行するdown関数を設定します。

新規のマイグレーションについては、テーブルを作る、あるいは削除するだけですので、テーブルの構成についてあまり気にする必要はありません。
しかし、既にあるテーブルの構成を変更する場合、作るときだけではなく、戻すときに元の構成に戻す処理を書かなくてはなりません。

さて、
今回は既存のテーブルに外部接続を設定する方法について記述します。

実装方法

今回はブログシステムを題材にします。

ブログの記事はテーマに分かれています。
ブログとテーマでそれぞれ次のテーブルが用意されていますが、まだ外部接続の設定をしていない状態だとします。

物理名 論理名
blogs ブログの記事
themes テーマ

ブログ(blogs)テーブルに、テーマと外部接続するためのIDを追加して、そのIDで外部接続できるようにします。

up関数

テーブルを新規に追加する手順とほぼ同じです。
外部接続するカラムを追加して、外部キーの設定をします。

<?php 

public function up()
{
    Schema::table('blog', function (Blueprint $table) {
    // テーマID追加
    $table->unsignedBigInteger('theme_id')    
        
        // 外部接続
    $table->foreign('theme_id')
        ->references('id')
        ->on('themes');
    });
}

【Tips】IDの型

尚、今回はthemesテーブル のIDがBiginteger型と言う想定で実装しています。
もし、themesテーブル のIDがinteger型だった場合は、外部接続するテーブルのIDも合わせてunsignedIntegerにしてください。

down関数

外部キーの解除はdropForgen関数を使用します。

readouble.com

外部キーの指定をする時は、外部接続するカラム名を配列値で渡してください。

もしくは配列値を渡せば、削除時に自動的に命名規則に従った名前が使用されます。
$table->dropForeign(['user_id']);
Laravel 5.8 データベース・マイグレーションより

<?php 

public function down()
{
    Schema::table('maintenance_phenomenon', function (Blueprint $table) {
        // 外部接続解除
        $table->dropForeign(['theme_id']);
        
        // 対象カラム削除
        $table->dropColumn('theme_id')
        
    });
}

外部キー名を直接指定する場合

以前外部キーの命名規則について触れましたが、外部キー名は自動で決まります。
ただし、直接指定する事もできます。

blog.websandbag.com

外部キーを直接指定した場合は、前述した外部接続するカラム名を設定する方法では解除できません
解除する際にはdropForeign関数に設定した外部キー名を設定します。

この場合、配列値ではなく、文字列で指定します。

<?php 

public function up()
{
    Schema::table('blog', function (Blueprint $table) {
        $table->unsignedBigInteger('theme_id')    
        
        // b_t_foreignと言う外部キーを設定
        $table->foreign('theme_id', 'b_t_foreign')
            ->references('id')
            ->on('themes');
    });
}

public function down()
{
    Schema::table('maintenance_phenomenon', function (Blueprint $table) {
        // 直接、b_t_foreignを設定する
        $table->dropForeign('b_t_foreign');
        $table->dropColumn('theme_id')
    });
}

©︎2017-2018 WebSandBag