【laravel】マイグレーション

# 概要
マイグレーションとはデータベースのテーブル作成や編集などを管理する機能です。
マイグレーション機能を活用することで、いつどのようなデータベースを作成・編集したかを時系列で管理できます。

マイグレーションは以下のような段階で構成されます。
１．一意な名前（いつ）のマイグレーションファイルを作成し、どのようなSQLをどの順番で実行したかを管理する。
２．マイグレーションコマンドを実行する。この時、実行されていないファイルがあった場合は順番に実行される。

マイグレーションファイルは「どんなテーブルを作るか」というテーブルの設計書で、その設計書を実行するのがマイグレーションの実行です。


# マイグレーションファイルの作成
ここでは以下のテーブルを例に作成していきます。
レジャー施設の体験に来たお客さんの顧客情報をイメージしました。

※ 補足
SQLiteのスキーマでVARCHAR(100)のように文字の長さを指定してもTEXT型として解釈するため、SQLiteのスキーマで文字の長さは指定しても意味がありません。

<table>
<tr>
<th>列名</th>
<th>型</th>
<th>PK</th>
<th>NOT NULL</th>
<th>DEFAULT</th>
</tr>

<tr>
<td>id</td>
<td>integer</td>
<td>✔</td>
<td>　　✔</td>
<td></td>
</tr>

<tr>
<td>name</td>
<td>varchar(100)</td>
<td></td>
<td>　　✔</td>
<td></td>
</tr>

<tr>
<td>tel</td>
<td>integer</td>
<td></td>
<td>　　✔</td>
<td></td>
</tr>

<tr>
<td>address</td>
<td>text</td>
<td></td>
<td>　　✔</td>
<td></td>
</tr>

<tr>
<td>email</td>
<td>varchar(255)</td>
<td></td>
<td></td>
<td></td>
</tr>

<tr>
<td>is_repeat</td>
<td>tinyiny</td>
<td></td>
<td>　　✔</td>
<td>　　0</td>
</tr>
</table>


## コマンド
マイグレーションのファイルはartisanコマンドで作成します。
まずはcreateでテーブルを作成するマイグレーションファイルを作成していきます。

オプション引数については下記しますが、オプション引数を指定しなければファイル名に依存したSchamaファサードで作成されます。
例えば、ファイル名に`create_xxxx_table`とすればSchema::createのメソッドで作成され、`edit_to_xxxx_table`とすればSchema::tableのメソッドで作成されます。
複数のパターンで試したところ`xxxx_to_xxxx_table`とすればtableメソッドで作成されました。

```:コマンド
// createメソッドの場合
php artisan make:migration create_sample_table

// tableメソッドの場合
php artisan make:migration edit_to_sample_table

```


## ディレクトリ構造
database\migrations内にコマンドで作成したファイルが`作成日時_ファイル名`で作成されます。

```:ディレクトリ
database
├─ migrations
|  ├─ xxxx_create_sample_table.php
```

## 作成されるファイル
artisanコマンドで作成した場合は以下のような内容が自動で作成されます。
長くなるのでコメント部分は割愛します。

マイグレーションファイルを作成した段階で`$table->increments('id')`と`$table->timestamps();`が準備されています。
`$table->increments('id')`は'id'がプライマリキーとなるオートインクリメントのカラムを追加するメソッドで、`$table->timestamps();`は作成日時の`created_at`と更新日時の`updated_at`のカラムを追加するメソッドです。

```php:xxxx_create_sample_table.php
<?php

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

class CreateTestTable extends Migration
{
  public function up()
  {
    Schema::create('sample', function (Blueprint $table) {
      $table->increments('id');
      $table->timestamps();
    });
  }

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

```


## マイグレーションの中身
マイグレーションファイルは`Illuminate\Database\Migrations\Migration`を継承して作成され、upメソッドとdownメソッドが用意されています。
upメソッドもdownメソッドも戻り値のないvoid型です。


### upメソッド
upメソッドはマイグレーションの実行に使用し、テーブルやカラムなどの値をデータベースへ追加するメソッドです。


### downメソッド
down メソッドはupメソッドが行った操作を元に戻すロールバック時に実行されます。


## make:migrationコマンドのオプション引数
`make:migration`コマンドには`--create`と`--table`のオプション引数が用意されています。
これらの引数はファイル名より優先して使用するメソッドを判断します。


### --create
make:migrationコマンドに`--create=テーブル名`とオプションを指定することでcreateメソッドのマイグレーションファイルを生成する処理を実行します。

たとえファイル名を`edit_to_xxxx_table`としてコマンド操作しても`--create`引数が指定されていればcreateメソッドを持ったマイグレーションファイルが生成されます。


### --table
make:migrationコマンドに`--table=テーブル名`とオプションを指定することでtableメソッドのマイグレーションファイルを生成する処理を実行します。

たとえファイル名を`create_xxxx_table`としてコマンド操作しても`--table`引数が指定されていればtableメソッドを持ったマイグレーションファイルが生成されます。



# カラムを追加する
カラムを追加するためにupメソッドを編集していきます。
laravelのSchemaは複数のカラムを指定できるため下記リンクをご参考ください。

[データベース：マイグレーション / カラム]
(https://readouble.com/laravel/6.x/ja/migrations.html#columns)
[データベース：マイグレーション / カラム修飾子]
(https://readouble.com/laravel/6.x/ja/migrations.html#column-modifiers)

```php:xxxx_create_sample_table.php
 public function up()
  {
    Schema::create('sample', function (Blueprint $table) {
      $table->increments('id');
      $table->string('name', 100);
      $table->integer('tel');
      $table->text('address');
      $table->string('email', 255)->nullable();
      $table->tinyInteger('is_repeat')->default(0);
      $table->timestamps();
    });
  }

// 記述方法
// increments('パラメータ');  ：INT型のオートインクリメントでPKとなる
// string('パラメータ', 文字数);  ：文字数指定のvarchar型
// integer('パラメータ');  ：INT型
// text('パラメータ');  ：TEXT型
// xxxx('パラメータ');->nullable()  ：NOT NULLのチェックを外す
// xxxx('パラメータ');->default(1)  ：default値の設定（ここでは0としている）
// timestamps();  ：dateTime型の作成日時と更新日時を生成
```


# マイグレーションの実行
作成したマイグレーションファイルを実行してデータベースにテーブルを作成する作業です。
設定と使用するデータベースが準備できていなければ、空のデータベースを作成しておいてください。

設定については以下のリンクをご参考ください。
[【laravel】データベースの設定（SQLiteの例）]
(https://qiita.com/gone0021/items/106b176012439841a3d9)

## コマンド
マイグレーションはartisanコマンドで実行します。
成功すれば以下のようなメッセージが表示されます。

```:コマンド
php artisan migrate
```

```:コメント
Migrating: xxxx_create_sample_table
Migrated:  xxxx_create_sample_table (0.01 seconds)

// xxxxは作成したマイグレーションファイルの作成日時
```


# ロールバック（テーブルの削除）
実行されたマイグレーション操作を元に戻します。

ここでdownメソッドが実行されます。
`Schema::dropIfExists('テーブル名');`は指定したテーブルがあれば削除して、なければ何もしない（エラーを返さない）というメソッドです。

```php:xxxx_create_sample_table.php
public function down()
{
  Schema::dropIfExists('sample');
}
```

## コマンド
ロールバックはartisanコマンドで実行します。
実行すれば以下のようなメッセージが表示されます。

```:コマンド
php artisan migrate:rollback
```


# リセット
全てのマイグレーション操作を初期化します。
全てがなくなります。

```:コマンド
php artisan migrate:reset
```


# リフレッシュ
全てのマイグレーション操作を初期化してから再実行します。
リフレッシュは全てのマイグレーション操作をリセットした後に`php artisan migrate`コマンドを実行します。

```:コマンド
php artisan migrate:refresh
```


# 現状の確認
`php artisan migrate:status`コマンドでマイグレーション操作の状態を確認できます。

```:コマンド
php artisan migrate:status
```

# 補足
`rollback`や`refresh`で`Class 'Doctrine\DBAL\Driver\PDOSqlite\Driver' not found`というエラーにはまった際の対処方です。
カラムを操作する際は`composer`で`doctrine/dbal`パッケージを追加する必要があるとのことでした。
以下のコマンドで追加します。

[データベース：マイグレーション /  カラム変更](https://readouble.com/laravel/6.x/ja/migrations.html#modifying-columns)

```:コマンド
composer require doctrine/dbal
```


# 既存のテーブルにカラムを追加する
ここではソフトデリートの`delete_at`カラムを追加します。
`add_soft_dlelet_to_people_table`というマイグレーションファイルを上記の順序で作成します。

既存のテーブルにカラムを追加するにはSchemaファサードのtableメソッドを使用します。
laravelではソフトデリート機能が用意されているのでupメソッドでは`softDeletes()`を呼び出すだけでカラム名を指定する必要はありません。
ただし、downメソッドではカラム名を指定する必要があるので注意してください。

追加するカラムについては以下をご参考ください。
[データベース：マイグレーション/ カラム]
(https://readouble.com/laravel/6.x/ja/migrations.html#columns)


```php:add_soft_dlelet_to_people_tabl.php
class AddSoftDleletToSampleTable extends Migration
{
  public function up()
  {
    Schema::table('sample', function (Blueprint $table) {
      $table->softDeletes();
    });
  }

  public function down()
  {
    Schema::table('sample', function (Blueprint $table) {
      $table->dropColumn('deleted_at');
    });
  }
}

```

# 参考
[データベース：マイグレーション]
(https://readouble.com/laravel/6.x/ja/migrations.html)
[データベース：マイグレーション / カラム]
(https://readouble.com/laravel/6.x/ja/migrations.html#columns)
[データベース：マイグレーション / カラム修飾子]
(https://readouble.com/laravel/6.x/ja/migrations.html#column-modifiers)
[Laravelにおけるマイグレーションのしくみ]
(https://www.hypertextcandy.com/how-laravel-migration-works)
[migrationの作成と実行方法]
(https://www.wakuwakubank.com/posts/450-laravel-migration/)