暇なときに予定を探せるアプリyoteiPickerをリリースしました。
この記事では、Laravelのマイグレーションですでにあるテーブルに外部キー制約を追加する方法を解説します。
Laravelのバージョンは6系です。
mysqlのバージョンは5.7系です。
>>フリーランスも対象!エンジニア転職におすすめなサイト5選
以下のようなテーブルがあったとします。
booksテーブル
book_id
book_name
categoriesテーブル
category_id
category_name
すでにどちらのマイグレーションも実行済みだけど、booksテーブルにcategory_idと外部キー制約を追加したいってときに使える記事です。
【完成系】
booksテーブル
book_id
book_name
category_id(外部キー制約)
まずはカラム追加のマイグレーションファイルを作成します。
php artisan make:migration add_category_id_to_books_table --table=books
マイグレーションファイルを編集します。
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddCategoryIdToBooksTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('books', function (Blueprint $table) {
// カラム追加
$table->bigInteger('category_id')->unsigned()->after('book_name');
// カラムの外部キー制約追加
$table->foreign('category_id')->references('category_id')->on('categories')->OnDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('books', function (Blueprint $table) {
// 外部キー制約の削除
$table->dropForeign('books_category_id_foreign');
// カラムの削除
$table->dropColumn('category_id');
});
}
}
マイグレーションを実行します。
php artisan migrate
## 解説
$table->bigInteger('category_id')->unsigned()->after('book_name');
bigInteger('category_id')
はcategoriesテーブルのcategory_idと型を合わせる必要があります。
categoriesテーブル
category_id
category_name
マイグレーションファイルでは、デフォルトで以下のように作成されるからです。
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateCategoriesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->bigIncrements('id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('categories');
}
}
categoriesテーブルのcategory_idはbigIncrementsなので、bigIntegerにしているってわけですね。
laravel5.8以前の場合は、categoriesテーブルのcategory_idはincrementsで作成されるでしょう。その場合は、integer('category_id')にする必要があります。
unsigned()->after('book_name')
のunsigned()は符号なし、つまりマイナスの数字は許容しない、'after('book_name')'でbook_nameカラムの後にcategory_idカラムが追加されるように指定しています。
まとめると、
$table->bigInteger('category_id')->unsigned()->after('book_name');
category_idのカラムの型はbigIntegerで符号なし、book_nameカラムの後にcategory_idカラムを追加って意味です。
$table->foreign('category_id')->references('category_id')->on('categories')->OnDelete('cascade');
foreign('category_id')->references('category_id')->on('categories')
外部キーはcategory_idで、参照するのはcategoriesテーブルのcategory_idだよって意味です。
OnDelete('cascade')
は決まり文句みたいなもので、
外部キー制約を CASCADE に設定することで、紐づいているレコードも含め一括で削除可能です。
// 外部キー制約の削除
$table->dropForeign('books_category_id_foreign');
// カラムの削除
$table->dropColumn('category_id');
downにはrollbackした時の操作を書きます。
dropForeign('books_category_id_foreign')
この部分ですが、
外部キーを追加するテーブル名_外部キー名_foreignとしてください。
downに外部キー制約の削除とカラムの削除を書かないと、rollbackできずにマイグレーションエラーとなりますので、ご注意を。
他にも記事書いているので、ぜひプロフィールからご参照ください。
・マイグレーション
・クエリビルダなど
書いています。
##既存テーブルから外部キー制約の削除
すでに外部キー制約のカラムがあるテーブルから外部キー制約のカラムを削除したいと思います。
まずはマイグレーションファイルを作成。
php artisan make:migration drop_category_id_to_books_table --table=books
マイグレーションファイルの編集
upに外部キー制約削除をdownにはrollbackしたときに元に戻す処理を書きます。
public function up()
{
Schema::table('books', function (Blueprint $table) {
// 外部キー制約の削除
$table->dropForeign('books_category_id_foreign');
// カラム削除
$table->dropColumn('category_id');
});
}
public function down()
{
Schema::table('books', function (Blueprint $table) {
// カラムの追加
$table->unsignedBigInteger('category_id')->after('user_id');
// 外部キーの追加
$table->foreign('category_id')->references('category_id')->on('categories');
});
}
##既存テーブルからカラムは削除したくないけど外部キー制約は解除したい場合
マイグレーションファイルを作成
php artisan make:migration drop_foreign_key_to_books_table --table=books
マイグレーションファイルを編集
public function up()
{
Schema::table('books', function (Blueprint $table) {
// 外部キー制約の削除
$table->dropForeign('books_category_id_foreign');
});
}
public function down()
{
Schema::table('books', function (Blueprint $table) {
// 外部キーの追加
$table->foreign('category_id')->references('category_id')->on('categories');
});
}
データベースを確認すると、外部キー名などが残ってしまいます。その場合は、以下のSQLを実行すれば外部キー名なども消えます。
データベースでSQLを実行
alter table books
drop index books_category_id_foreign
暇なときに予定を探せるアプリyoteiPickerをリリースしました。
>>Laravelのマイグレーションが怖くない【作成・カラムの追加・削除】
>>【Laravelクエリビルダ】複数のカラムをgroupByでグループ化させる