Laravel忘備録-カラムの文字数を変更するマイグレーション-

カラムの文字数を変更するマイグレーションファイルを作成する機会があったため忘備録として記録に残そうと思います。

# 想定するデータ

usersテーブル

```
+---------------+---------------------+------+-----+---------+----------------+
| Field         | Type                | Null | Key | Default | Extra          |
+---------------+---------------------+------+-----+---------+----------------+
| id            | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| name          | varchar(50)         | NO   |     | NULL    |                |
| created_at    | timestamp           | YES  |     | NULL    |                |
| updated_at    | timestamp           | YES  |     | NULL    |                |
+---------------+---------------------+------+-----+---------+----------------+
```

# nameの文字数を50→200に変更したい

## 1. マイグレーションファイルを作成する

```
$ php artisan make:migration change_name_on_users_table --table=users
   INFO  Migration [database/migrations/2024_08_26_094250_change_name_on_users_table.php] created successfully.  
```

→ 2024_08_26_094250_change_name_on_users_table.php というマイグレーションファイルが作成されます。

## 2. マイグレーションファイルを編集する

upメソッドに変更したい内容を記述します。
→ nameの文字数を50→200に増やす変更

downメソッドには上記の変更を戻す内容を記述します。
ロールバック(マイグレーションファイルの変更を戻す）時に実行されます。
→ nameの文字数を200→50に減らす変更

2024_08_26_094250_change_name_on_users_table.php
```
<?php

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

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            // nameの最大文字数を50文字→200文字に変更
            $table->string('name', 200)->change();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            // nameの最大文字数を200文字→50文字に戻す
            $table->string('name', 50)->change();
        });
    }
};

```

## 3. マイグレーションファイルを実行する

以下のコマンドでマイグレーションの状態を確認します。
1.で作成したマイグレーションファイルがPending状態であることを確認できました。

```
$ php artisan migrate:status

  Migration name .............................................. Batch / Status  
  2024_08_26_094250_change_name_on_users_table .......................... Pending  
```

実行します。

```
$ php artisan migrate

   INFO  Running migrations.  

  2024_08_26_094250_change_name_on_users_table .................... 56ms DONE
```

usersテーブルのnameの文字数が200に変更されていることを確認できました。

```
+---------------+---------------------+------+-----+---------+----------------+
| Field         | Type                | Null | Key | Default | Extra          |
+---------------+---------------------+------+-----+---------+----------------+
| id            | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| name          | varchar(200)        | NO   |     | NULL    |                |
| created_at    | timestamp           | YES  |     | NULL    |                |
| updated_at    | timestamp           | YES  |     | NULL    |                |
+---------------+---------------------+------+-----+---------+----------------+
```

## 4. ロールバック確認

nameに200文字のデータが格納されている状態で、文字数を50字へと変更した場合にどうなるのか、実際に確認してみました。

```
$ php artisan migrate:rollback

   INFO  Rolling back migrations.  

  2024_08_26_094250_change_name_on_users_table ................... 47ms FAIL

   Illuminate\Database\QueryException 

  SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column 'name' at row 82 (SQL: ALTER TABLE users CHANGE name name VARCHAR(50) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_unicode_ci`)

  at vendor/laravel/framework/src/Illuminate/Database/Connection.php:760
    756▕         // If an exception occurs when attempting to run a query, we'll format the error
    757▕         // message to include the bindings with SQL, which will make this exception a
    758▕         // lot more helpful to the developer instead of just the database's errors.
    759▕         catch (Exception $e) {
  ➜ 760▕             throw new QueryException(
    761▕                 $query, $this->prepareBindings($bindings), $e
    762▕             );
    763▕         }
    764▕     }

      +9 vendor frames 
  10  database/migrations/2024_08_26_094250_change_name_on_users_table.php:32
      Illuminate\Support\Facades\Facade::__callStatic("table")

      +25 vendor frames 
  36  artisan:37
      Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
```

→ 桁数のエラーとなり、ロールバックできないことがわかりました。
200字のデータを削除後に、再度ロールバックを実行すると正常に動作することを確認しました。


# 参考資料

https://qiita.com/masuda-sankosc/items/2a6999cca62de4facd45

# 告知

最後にお知らせとなりますが、イーディーエーでは一緒に働くエンジニアを
募集しております。詳しくは採用情報ページをご確認ください。

https://eda-inc.jp/recruit/

みなさまからのご応募をお待ちしております。