【Laravel】マイグレーションの基礎


#はじめに
Laravelでの共同開発で自身が担当したタスクをまとめていきます。
初学者のため学習のアウトプットしての意味と備忘録としての意味で書いています。
もし間違いがありましたらコメントにてご指摘いただけますと幸いです。

#マイグレーションとは
マイグレーションとはデータベースのバージョン管理機能。

##マイグレーションのメリット
マイグレーションを使わずDB作成、テーブル作成をする時はSQLコマンド、phpmyadminですることも可能です。
ただ、チーム開発の場合１人１人がSQLコマンドを実行したりするよりもマイグレーションを使うとマイグレーションファイルを共有してartisanコマンドを実行するだけでチーム全員同じDBの作成が簡単にできることがメリットです。

##マイグレーションファイル作成
artisanコマンドを使用しマイグレーションファイルを作成する。
`$ php artisan make:migration create_users_table`

作られたファイルの場所は`database/migrations`フォルダに設置される。


#マイグレーションの実行
database/migrationsフォルダにはあらかじめ3つのファイルが用意されています。
Laravelの場合これらをマイグレーションするだけでログイン機能ができるのですごく簡単です。

```
$ php artisan migrate:status

| Ran? | Migration                                      | Batch |
+------+------------------------------------------------+-------+
| No   | 2014_10_12_000000_create_users_table           |       |
| No   | 2014_10_12_100000_create_password_resets_table |       |
| No   | 2019_08_19_000000_create_failed_jobs_table     |       |
+------+------------------------------------------------+-------+
```

実際に使う際は必要なテーブル1つ1つにファイルを作成してマイグレーションをしていきます。
ここでは簡単な記事投稿サービスを作ると仮定してマイグレーションファイルを作成したいと思います。

```
//articlesテーブル作成
$ php artisan make:migration creagte_articles_table --create=articles
//categoriesテーブル作成
$ php artisan make:migration create_categories_table --create=categories

$ php artisan migrate:status
+------+------------------------------------------------+-------+
| Ran? | Migration                                      | Batch |
+------+------------------------------------------------+-------+
| No   | 2014_10_12_000000_create_users_table           |       |
| No   | 2014_10_12_100000_create_password_resets_table |       |
| No   | 2019_08_19_000000_create_failed_jobs_table     |       |
| No   | 2022_02_06_175033_create_categories_table      |       |
| No   | 2022_02_06_175054_create_articles_table        |       |
+------+------------------------------------------------+-------+

```
必要なマイグレーションファイルが作成されました。
まだこの段階ではただファイルを作成しただけなので、DBにテーブルは作成されていません。
なので、間違って作ってしまったらファイルを消せばOKです。

```2022_02_06_175054_create_articles_table.php
<?php

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

class CreateArticlesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        if (!Schema::hasTable('articles')) {
            Schema::create('articles', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->unsignedBigInteger('user_id');
                $table->string('title');
                $table->unsignedBigInteger('category_id');
                $table->string('summary');
                $table->string('url');
                $table->dateTime('created_at');
                $table->dateTime('updated_at');
                $table->softDeletes();

                //外部キー制約
+            $table->foreign('user_id')->references('id')->on('users')->onUpdate('CASCADE')->onDelete('CASCADE');
                $table->foreign('category_id')->references('id')->on('categories');
            });
        }
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('articles');
    }
}
```
今回はこのような感じでカラム作成を行いました。マイグレーションファイルのupメソッド内でカラムの制約などを設定できます。
この中で重要なものはupメソッドとdownメソッドです。
これがどういったものか解説していきます。

##upメソッドとは
マイグレーションが実行されたときに行われるメソッドです。
具体的には`php artisan migrate`が行われるとこのメソッド内の処理が実行されます。

##downメソッドとは
ロールバックが実行された時に行われるメソッドです。
`php artisan migrate:rollback`が行われた時に実行されます。

```
デフォルトではこうなっています。
articlesテーブルがあったら削除するという意味です。

public function down()
    {
        Schema::dropIfExists('articles');
    }
```

##ロールバックとは
プログラミングを勉強していてわからない単語は多く出てきます。
このロールバックという言葉も私は例に漏れず当初はわかりませんでした。

ロールバックとは「やりかけの処理を取り消すこと」です。
もう少し具体的に書くと1かたまりの処理を取り消すことです。

「１かたまり」とはBatchということです。

```
$ php artisan migrate:status
右側にBatchと書かれている。
+------+------------------------------------------------+-------+
| Ran? | Migration                                      | Batch |
+------+------------------------------------------------+-------+
| No   | 2014_10_12_000000_create_users_table           |       |
| No   | 2014_10_12_100000_create_password_resets_table |       |
| No   | 2019_08_19_000000_create_failed_jobs_table     |       |
| No   | 2022_02_06_175033_create_categories_table      |       |
| No   | 2022_02_06_175054_create_articles_table        |       |
+------+------------------------------------------------+-------+
```
ここでマイグレーションを実行すると、Batchが１になる。

```
$ php artisan migrate
$ php artisan migrate:status
Batchが1になっている。これが１かたまりということ。

+------+------------------------------------------------+-------+
| Ran? | Migration                                      | Batch |
+------+------------------------------------------------+-------+
| Yes  | 2014_10_12_000000_create_users_table           | 1     |
| Yes  | 2014_10_12_100000_create_password_resets_table | 1     |
| Yes  | 2019_08_19_000000_create_failed_jobs_table     | 1     |
| Yes  | 2022_02_06_175033_create_categories_table      | 1     |
| Yes  | 2022_02_06_175054_create_articles_table        | 1     |
+------+------------------------------------------------+-------+
```
ロールバックはこの1かたまりの処理を取り消すことです。
この状態でロールバックを行うと、それぞれのdownメソッドが実行されます。
今回の場合はテーブルが削除されます。

##カラム追加や変更などがあった時
例えばarticlesテーブルに後からカラム追加をする必要があった場合
現在のarticlesのマイグレーションファイルを修正してもマイグレーションが既に実行されているので、
再度行われることはありません。

そのため、新たにマイグレーションファイルを作成することでテーブルの変更履歴が追いやすくなります。


###カラム追加
```
php artisan make:migration add_comment_to_articles_table --table=articles
```

マイグレーションファイルの中身はこうします。
up()の時にカラム追加を行って、ロールバックされた時には追加されたカラムを削除するようにしておきます。
こうすることでロールバックするとこのマイグレーションをする前に戻ります。

```add_comment_to_articles_table.php
 public function up()
    {
        Schema::table('articles', function (Blueprint $table) {
+            $table->string('comment');  //カラム追加
        });
    }


    public function down()
    {
        Schema::table('articles', function (Blueprint $table) {
+           $table->dropColumn('comment');  //カラムの削除
        });
    }
```

#マイグレーションコマンド

```
マイグレーション実行（マイグレートされていないすべてのマイグレーションファイルを実行）
$ php artisan migrate

マイグレーション状況の確認
$ php artisan migrate:status

最新のマイグレーション（Batchの数値が1番大きいもの）をロールバック
$ php artisan migrate:rollback

全てロールバックしてマイグレーション実行
$ php artisan migrate:refresh

一旦すべてのテーブルを削除してロールバック
$ php artisan migrate:fresh

```
以上です。最後の方は駆け足になってすみません。。。