LaravelマイグレーションでDB構築~Seederで初期データ投入するまで

#マイグレーションとは
マイグレーションとは、PHP MyAdminから行うような、データベースにテーブルを追加作成したり、カラムを追加、変更、削除したり…といった作業を、コマンド一発で簡単にできる機能です。
もちろん、環境が変わった場合でも使えるので、マイグレーションを使ったことがない人には是非、覚えて欲しい機能です。

##マイグレーションの手順
####1. マイグレーションファイルを作成する
コマンドを使って簡単にマイグレーションファイルを作成することが出来ます。

####2. 作成されたマイグレーションファイルに、処理を記述する
テーブル作成や、カラム追加、削除などの処理をPHPで記述します。
記述方法については、以下でご紹介します。

####3. マイグレーションを実行する
コマンドを使って、マイグレーションを実行します。
マイグレーション実行後、データベースに変更や追加が反映されているか確認します。


#Doctrine DBALライブラリーの導入
Laravelは、defaultではカラム変更のmygrationは実行出来ないため、Doctrine DBALライブラリーを追加する必要があります。

これを入れておかないと、カラム変更のマイグレーションを実行した際に以下のようなエラーが出ます。

```
 Changing columns for table "テーブル名" requires Doctrine DBAL; install "doctrine/dbal".
```

##導入手順
Laravelルートディレクトリへ移動して、以下のコマンドを実行します。

```
composer require doctrine/dbal
```
※Version差異によるエラーが出ることあり

##導入の確認方法
laravel/composer.jsonを開いてdoctrine/dbalが追加されていればOK

```
    "require": {
        "php": "^7.1.3",
        "doctrine/dbal": "^2.9",//※追加
        "fideloper/proxy": "^4.0",
        "laravel/framework": "5.8.*",
        "laravel/tinker": "^1.0",
        "nesbot/carbon": "^2.16.0",
```
※以下のカラムタイプのみ変更可能
```bigInteger、binary、boolean、date、dateTime、dateTimeTz、decimal、integer、json、longText、mediumText、smallInteger、string、text、time、unsignedBigInteger、unsignedInteger and unsignedSmallInteger```


##1：マイグレーションファイル作成

Laravelでデータベースを扱うために、テーブル作成とモデルファイル作成の方法をご紹介します。
###Laravelでテーブルを作成するコマンド
例：XXXテーブルを作成

```
php artisan make:migration [マイグレーションファイル名] --create=[テーブル名]
php artisan make:migration create_XXX_table --create=XXX
```
※マイグレーションファイル名はそのままクラス名になるので、分かりやすい名前をつけること
※生成出力先のパスを指定したい場合は、make:migrateコマンドの実行時に--pathオプションを付ける。（Laravelルートディレクトリからの相対パスで指定）


######例：Reservationsテーブルを作成する場合
```
php artisan make:migration create_reservations_table --create=reservations
```
上記のコマンド実行すると、以下のようなファイルが生成されます。
```マイグレーション用ファイル：コマンド実行日時＋create_reservations_table.php```
```作成される場所：プロジェクトフォルダ\database\migrations```

※この段階ではまだテーブルは作成されていません。


###生成されたファイル
create_reservations_table.phpを開いてみます。
「CreateReservationsTable」というクラス名でファイルが生成されているのが確認できます。

#####upメソッド
upメソッド内にテーブル追加・変更の内容を記述していきます。
ここに記述された内容が、マイグレート(migrate)コマンドを叩いた時に、実行される処理です。

```
public function up()
    {
        Schema::create('flights', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->string('airline');
            $table->timestamps();
        });
    }
```
#####downメソッド
ここにはロールバック(rollback)した時に、実行される処理を記述します。
例えば、ロールバック時、テーブルを削除したい場合は以下のように記述します。

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

###マイグレーション実行
とりあえずテーブルを作成してみたいので、マイグレーションを実行してみます。
以下のコマンドを叩きます。

```
php artisan migrate
```

以下のように「Migrated」と表示されればOK。マイグレーション実行は成功しています。

```
Migrating: 2020_10_19_154405_create_reservations_table
Migrated:  2020_10_19_154405_create_reservations_table (37.32ms)
```

#####実行されたSQL文を確認するコマンド
実行されたSQL文を確認したい場合は、以下のコマンドを叩きます。

```
php artisan migrate --pretend
```

###全テーブルを削除してマイグレーションをやり直したい場合

```
php artisan migrate:reset
```
resetコマンドはdown メソッドを呼び出し、アプリケーション全部のマイグレーションをロールバックします。
実行後、DBのmigrationsテーブルが空になっているのが確認できます。

※resetコマンドはあくまでもロールバックのみなので、テーブル削除＋マイグレーション再実行を一発で済ませたい場合は、refreshコマンドを使うと便利です。


###カラムの追加、名前変更、属性変更、削除
ここまでの手順後、カラムの追加、名前変更、属性変更、削除が必要な場合は、それ用のファイルを別で作成し、再度マイグレーションを実行します。







###カラム名を変更
まず、カラム変更用のマイグレーションファイルを作成するため、以下のようにコマンドを叩きます。

```
php artisan make:migration rename_変更前のカラム名_to_変更後のカラム名_on_テーブル名_table --table=テーブル名
```
作成されたファイルを開いて編集します。

####`カラム名を変更する：renameColumnメソッド`

```.php
Schema::table('users', function (Blueprint $table) {
    $table->renameColumn('from', 'to');
});
```
※カラムタイプがenumのカラム名変更は、Version5.5時点ではサポートされていない

###カラム属性の変更
まず、カラム属性変更用のマイグレーションファイルを作成するため、以下のようにコマンドを叩きます。

```
php artisan make:migration changecolumn_属性変更するカラム名_テーブル名_table --table=テーブル名
```
作成されたファイルを開いて編集します。

####`カラム属性を変更する：changeメソッド`
例：nameカラムのサイズを25から50へ増やす

```
Schema::table('users', function (Blueprint $table) {
    $table->string('name', 50)->change();
});
```
###カラムの追加
####`既存テーブルにカラムを追加する`

####生成されたファイルを編集
```
    public function up()
    {
        Schema::table('abc;', function (Blueprint $table) {
            $table->integer('test')->default(0)->index('index_test')->after('aaa')->comment('新カラム');
        });
    }
```
####カラム追加時の修飾子
- afterメソッド：どのカラムの後に追加するかを指定
- nullableメソッド：null値許容
- nullableメソッドに引数false指定：not null
- 型指定：tinyInteger('test')
- default null挿入:nullable($value = true)
- TIMESTAMPカラムのデフォルト値をCURRENT_TIMESTAMPに指定：useCurrent()

`※第二引数はauto_increment、第三引数はprimary keyの指定なので、String型のように第二引数は長さの指定ではないことに注意`

###カラムの削除
####`既存テーブルを削除：dropColumnメソッド`
引数に配列を渡して複数削除可

```
Schema::table('users', function (Blueprint $table) {
    $table->dropColumn(['votes', 'avatar', 'location']);
});
```





#DBに初期データを投入（Insert)
マイグレーションでDBを構築したら、シーディングで初期データを投入してみます。

###Seedファイルの生成
投入データ用Seedファイルを生成するため、以下のコマンドを実行します。
※Reservationsテーブルへのシーダーを生成するのであれば「ReservationsTableSeeder」といったクラス名にする

```
php artisan make:seeder ReservationsTableSeeder
```
以下が表示されればOK。作成

```
Seeder created successfully.
```

###データ投入の記述
プロジェクトフォルダ\database\seeders\配下にReservationsTableSeeder.phpファイルが生成されているので、開いてデータを投入する記述を追加します。


```ReservationsTableSeeder.php
<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;//←追加

class ReservationsTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        //ここにデータを投入する記述
    }
}
```

1レコード分の投入であれば以下のように記述します。複数レコードは、配列でその下に追加します。

```ReservationsTableSeeder.php
       DB::table('users')->insert([
        [
            'name' => '木村',
            'email' => 'kimura@XXX.co.jp',
            'password' => '123456',
            'user_id' => 'kimura3',
            'auth_id' => 1,
            'last_login_date' => date('Y-m-d H:i:s'),
        ],
```

###実行時に呼び出す記述を追加
シーダクラスを定義したら、このシーダクラスをシーディング実行時に呼び出す記述を追加します。
seedsディレクトリ内DatabaseSeeder.phpに以下を記述します。登録したいシーダクラスが複数ある場合は、ここに配列で追加します。 

```DatabaseSeeder.php
<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        $this->call([
            ReservationsTableSeeder::class,
         ]);
    }
    
}
```


###シーディングの実行
プロジェクトフォルダで以下コマンドを実行します。

```
php artisan db:seed
```

####ファイル名を指定して実行する場合
上の手順で呼び出し用の記述をDatabaseSeeder.phpにしましたが、optionでファイル名を指定する場合は、記述しなくても実行できます。

```
php artisan db:seed --class=UsersTableSeeder
```

####DB確認
テーブルにデータが作成されている事が確認できます。


##LaravelでModelを作成するコマンド
例：XXXモデルを作成

```
php artisan make:model XXX
```
上記コマンド実行後、プロジェクトルート/appにXXX.phpというModelファイルが作成されているのが確認できます。