初めに
初めまして。一月に未経験でエンジニアとして入社しました。ミツキと申します。
今回はLaravelのマイグレーション作成時に使用するdownメソッド
について備忘録として書いていきます。
というのも、今までdownメソッドを活用した事がなく、$ php artisan migrate:rollback
をした際に、全てリセットされたり、それによって$ php artisan migrate
を実行する際に「本当にこの設計でいいのか。。。?」などといった不安からマイグレーション作成に関する作業が滞ったりしていました。そんな中会社の上司から「downメソッドを活用したらその不安は解消するよ」とういった助言をいただいたので、今回は実際に検証しながらアウトプットしようと考えた次第です。この記事を読んでの感想などがありましたら、フィードバックをいただけると幸いです。
downメソッドとは
- テーブル削除の定義を記述するメソッド。
- upメソッドが行った操作を元に戻す。
migrationを実行して、「やっぱ元に戻したい。。。」という場合にロールバックを実行するのですが、その際に実行される内容を設定していきます。
具体的には、マイグレーションファイルを編集する際に「編集する前のテーブルの状態」を記載しておくことで編集が失敗した際でもrollbackすることで前のテーブルの状態に戻す事ができる。
なので今回は、テーブルを編集するといった前提で記事を書きたいと思います。
実践
初めのテーブルの状態
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
$table->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP'));
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
この場合、$ php artisan migrate
を実行するとdownメソッドのSchema::dropIfExists('users');
この記述が実行されることになります。
この記述はというと、引数であるusers
テーブルが存在していた場合、それを削除するメソッド。
テーブル概要
+-------------------+-----------------+------+-----+-------------------+-----------------------------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+-----------------+------+-----+-------------------+-----------------------------------------------+
| id | bigint unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
| email | varchar(255) | NO | UNI | NULL | |
| email_verified_at | timestamp | YES | | NULL | |
| password | varchar(255) | NO | | NULL | |
| remember_token | varchar(100) | YES | | NULL | |
| created_at | timestamp | NO | | CURRENT_TIMESTAMP | DEFAULT_GENERATED |
| updated_at | timestamp | NO | | CURRENT_TIMESTAMP | DEFAULT_GENERATED on update CURRENT_TIMESTAMP |
| deleted_at | timestamp | YES | | NULL | |
+-------------------+-----------------+------+-----+-------------------+-----------------------------------------------+
テーブルを編集する
次に、テーブルを以下のように編集を加えてみます。
まずはマイグレーションファイルの作成
$ php artisan make:migration change_users_table --table=users
Created Migration: 2021_02_21_155512_change_users_table
新しく作成した編集用マイグレーションファイルを記述
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->renameColumn('name', 'user_name'); // カラム名変更
$table->dropUnique('users_email_unique'); // emailをUniqueから外す
$table->tinyInteger('gender')->after('email'); // emailの後ろにgenderカラムを追加
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->renameColumn('user_name', 'name'); // カラム名を元の名前に変更
$table->string('email')->unique()->change(); // emailをUniqueに設定する
$table->dropColumn('gender'); // genderカラムの削除
});
}
さて、どーなるんやろ。。。(ワキワキ)
いつもマイグレーション実行時は一発で決まらないのでやたらドキドキします
いざ、$ php artisan migrate
。
。
。
。
。
結果40分ぐらいエラーと格闘しました(小声)
今回の記事と関係なくなってしまうのでエラー解決の内容はまた次回。。。
変更後のテーブルの状態
+-------------------+-----------------+------+-----+-------------------+-----------------------------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+-----------------+------+-----+-------------------+-----------------------------------------------+
| id | bigint unsigned | NO | PRI | NULL | auto_increment |
| user_name | varchar(255) | NO | | NULL | |
| email | varchar(255) | NO | | NULL | |
| gender | tinyint | NO | | NULL | |
| email_verified_at | timestamp | YES | | NULL | |
| password | varchar(255) | NO | | NULL | |
| remember_token | varchar(100) | YES | | NULL | |
| created_at | timestamp | NO | | CURRENT_TIMESTAMP | DEFAULT_GENERATED |
| updated_at | timestamp | NO | | CURRENT_TIMESTAMP | DEFAULT_GENERATED on update CURRENT_TIMESTAMP |
| deleted_at | timestamp | YES | | NULL | |
+-------------------+-----------------+------+-----+-------------------+-----------------------------------------------+
いい感じですね!!!(^^;)www
想定通り、変更したい箇所を変更できました!
さて問題はお次。$ php artisan migrate:rollback
で元の状態に戻るのか。。。
$ php artisan migrate:rollback
!!!
mysql> desc users;
ERROR 1146 (42S02): Table 'training_app_axis.users' doesn't exist
あっれれ〜〜〜???????( ^ω^ )
空っぽだと。。。??
rollbackはdowmメソッドを決行するんじゃ。。。待てよ、
public function down()
{
Schema::dropIfExists('users');
}
なるほどお前か( ^ω^ )
もともと作成したマイグレーションファイルのdownメソッドが実行されていただけでした。
ここをコメントアウトした状態で再度繰り返し実行。
+-------------------+-----------------+------+-----+-------------------+-----------------------------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+-----------------+------+-----+-------------------+-----------------------------------------------+
| id | bigint unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
| email | varchar(255) | NO | UNI | NULL | |
| email_verified_at | timestamp | YES | | NULL | |
| password | varchar(255) | NO | | NULL | |
| remember_token | varchar(100) | YES | | NULL | |
| created_at | timestamp | NO | | CURRENT_TIMESTAMP | DEFAULT_GENERATED |
| updated_at | timestamp | NO | | CURRENT_TIMESTAMP | DEFAULT_GENERATED on update CURRENT_TIMESTAMP |
| deleted_at | timestamp | YES | | NULL | |
+-------------------+-----------------+------+-----+-------------------+-----------------------------------------------+
今度はしっかりとchange_users_table.php
のdownメソッドで記述した内容が反映され、元のテーブルへと戻す事ができました!!
まとめ
今回はマイグレーションのロールバックを実際に行いながら記事を書いてみました。
複数のエラーと戦っているうちにマイグレーションの耐性も少し身についたように感じます。
これまでは、ロールバックを行うと「一つ前のテーブルの状態に戻る」といった認識でしかありませんでしたが、
「ロールバック->downメソッドの実行」の感覚が掴めたと思うのでさまざまな場面で使用頻度を高めていきたいと思います。
使ってみるととても便利に感じたことから、やはり「知らないは罪」なんだなーと改めて実感。