【Laravel】マイグレーションを理解しよう。

## はじめに

この記事は、PHP、Laravel9での学習の過程で疑問を解決するために、まとめた記事になります。間違い等があるかと思いますが、あらかじめご容赦ください。

## 環境

MacOS 14.5
PHP 8.1.31
Laravel Framework 9.52.18
にて行っています。

## 疑問

Laravelの学習をしている際に、DBの操作をPHPファイルで記載してできるよ〜。といった、内容の回がありファイルを作って、マイグレーションを行いました。
結果、DBが作成されてGUI上からデータも追加できるようになりました。やったね。
ここで、気になったのは、カラムの追加やデータの追加はどうするんだ…？となりました。そして、ファイルを書き換えてマイグレーションを実施…。
~~~md:ぼくのたーみなる
INFO  Nothing to migrate. 
~~~
DBが更新されません。
ぼく「は？？」

## 目標

Laravelのマイグレーションを使って、データベースのテーブル作成・変更・データ挿入を行う手順を解説します。順を追って操作を見ていきましょう。


## 実践

順を追って、DBに対して何を行ったか見ていきましょう。

~~~md:ターミナル
php artisan make:migration create_message_test_table
~~~

これを、行うと実行ディレクトリから見て、`database/migrations`のディレクトリに`2024_12_17_110000_create_message_test_table.php`が作成されます。(日時部分はmake:migrationの実施タイミング)
今作成された、PHPファイルを見ると
```ruby:PHP
    public function up()
    {
    // 新しいテーブル 'message_test' を作成
    Schema::create('message_test', function (Blueprint $table) {
        $table->id();  // IDカラムを作成
        $table->timestamps();  // created_at と updated_at カラムを作成
    });
    }
```
となっています。`function up()`は、`php artisan migrate` コマンド実行時に適用される処理となっていて、今回の処理では、テーブルにIDとタイムスタンプが記録されるテーブルが作成されます。
```ruby:PHP
    public function down()
    {
        Schema::dropIfExists('message_test');
        //テーブル 'message_test'の削除
    }
```
となっています。`function down()`は、`php artisan migrate:rollback`、`php artisan migrate:reset` などのコマンド実行時に適用される処理(upの内容を取り消す処理)となっていて、今回の処理では、message_testテーブルが削除されます。
実施してみると
~~~md:ターミナル
php artisan migrate  

   INFO  Running migrations.  

  2024_12_17_110000_create_message_test_table ........................ 17ms DONE
  ~~~
|id|created_at|updated_at|
|:-:|:-:|:-:|
|   |   |   |

空のテーブルができました。

## 応用編

空のテーブルにカラムを追加したり、データを挿入することはGUIでも可能ですが、ここではLaravelのマイグレーションを使って行ってみましょう。
学習時の認識は、

:::note alert
すでにあるマイグレーションのファイルを操作して、再度マイグレーションを行う
:::

でしたが、この実装ではDBを作成し直す(ロールバックやリフレッシュ)場合に再度マイグレーションを行う形であれば更新できます。(つまりDBがリセットされます)
よって、データやカラムを追加する場合は、

:::note info
新しく作ったマイグレーションのファイルに記載してDBの情報を上書きする
:::

ということだったのです。
### 追加するカラムをマイグレーションで設定

~~~md:ターミナル
php artisan make:migration add_columns_to_message_test_table --table=message_test
~~~
を実行して、`message_test`テーブルに対してデータを書き込めるphpファイルを作成します。

### 新しいカラムを追加

```ruby:PHP
    public function up()
    {
        Schema::table('message_test', function (Blueprint $table) {
            $table->text('text')->nullable(); 
            $table->boolean('deleted')->default(false);
        });
    }

    public function down()
    {
        Schema::table('message_test', function (Blueprint $table) {
            $table->dropColumn(['text', 'deleted']); 
        });
    }
```

として、`php artisan migrate`を実行することで、
|id|created_at|updated_at|text|deleted|
|:-:|:-:|:-:|:-:|:-:|
|   |   |   |   |   |

`message_test`テーブルに加えられる情報が増えました。
### 追加するデータをマイグレーションで設定
~~~md:ターミナル
php artisan make:migration add_data_to_message_test_table --table=message_test
~~~
### 新しいデータを追加
同様にデータ追加用のPHPファイルを作成して
```ruby:PHP
    public function up()
    {
        // message_test テーブルにデータを挿入
        DB::table('message_test')->insert([
            [
                'id' => 1,
                'text' => 'sample1',
                'deleted' => false,
                'created_at' => now(),
                'updated_at' => now(),
            ],
            [
                'id' => 2,
                'text' => 'sample2',
                'deleted' => true,
                'created_at' => now(),
                'updated_at' => now(),
            ],
        ]);
    }

    public function down()
    {
        // 挿入したデータを削除
        DB::table('message_test')->whereIn('id', [1, 2])->delete();
    }
```
ここで、DB::table('message_test')->insert([...]) は、message_test テーブルに新しいレコードを一度に挿入するための方法です。
として、`php artisan migrate`を実行することで、

|id|created_at|updated_at|text|deleted|
|:-:|:-:|:-:|:-:|:-:|
|1|24/12/17-11:30:00|24/12/17-11:30:00|sample1|false|
|2|24/12/17-11:30:00|24/12/17-11:30:00|sample2|true|

テーブルにデータが加わりました。

## down()の働きについて

冒頭でも触れたように、`function down()`は、`php artisan migrate:rollback`、`php artisan migrate:reset` などのコマンド実行時に適用される処理(upの内容を取り消す処理)となっています。
今回は、`php artisan migrate:rollback`を行った場合のみ触れてみます。

マイグレーション用のファイルは必ず

**YYYY_MM_DD_HHMMSS**(hoge).php

と、タイムスタンプが押され、新しい順に処理します。

マイグレーションをロールバックする場合、`php artisan migrate:rollback` を実行すると、最後に実行されたマイグレーションが元に戻ります。この際、`down()` メソッドに定義された処理が実行されます。

例えば、以下のように `message_test` テーブルにデータを挿入するマイグレーションを実行した後、ロールバックを行うと、挿入したデータが削除され、テーブルは元の状態に戻ります。

```ruby:PHP
    public function down()
    {
        // 挿入したデータを削除
        DB::table('message_test')->whereIn('id', [1, 2])->delete();
    }
```

この処理が走り、

|id|created_at|updated_at|text|deleted|
|:-:|:-:|:-:|:-:|:-:|
|   |   |   |   |   |

`message_test`テーブルの中身がロールバックされました。

## まとめ
Q.マイグレーションって何するの？？
A.マイグレーションは、データベースのスキーマを管理するためのツール。

新しいテーブルやカラムを追加したり、既存のテーブルを変更する際にマイグレーションを使用します。これにより、データベースの変更をチームで共有したり、**環境を再構築する際に一貫性を保つ**ことができます。

:::note info
DBのスキーマを手動で変更せずに、マイグレーションを通じて変更を管理する
:::