LaravelでDBにテストデータを仕込む

LaravelでDB周りをいろいろしてみる。
まずはテーブルの設定からテストデータを仕込むところまでやってみる。

#データベースを準備する
Laravelをインストールすると、.envに勝手にDBが設定される。

```php:.env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
```

homesteadの環境にインストールすると、データベース名やユーザー名にhomesteadが設定される。
Laravel起動前にDB_DATABASEを作成したいデータベース名に、また、DB_USERNAMEにMySQLのユーザー名を設定すると、Laravel起動時にデータベースやユーザーを作ってくれます。うっかり先にLaravelを立ち上げると、いらないDBやユーザーを作ってしまうので注意。

#テーブルを準備する
##マイグレーションファイルを作る
テーブルはmigrateでcreateしてもらうのが吉。
まずはartisanでマイグレーションファイルを作成する。

```
$php artisan make:migration [ファイル名]
```

ファイル名は何でもいいらしいが、サンプルで入っている形に合わせたほうがわかりやすそうである。但し、先頭の日付や拡張子は自動でつけられるので、その辺はつけずに指定するように。
例えばこんな感じ。

```
$php artisan make:migration create_admin_table
```

そうすると/database/migrationsの中に、例によってマイグレーションファイルの枠だけ作成される。
こんな感じ。

```php:create_admin_table.php
<?php

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

class CreateAdminTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('admin', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('admin');
    }
}
```

Schema::createの中に$tableでカラムを設定していく。
$table->{属性}('{物理名}');

属性はstringとかintegerとか指定する。いろいろ指定できるので、ちゃんとマニュアル見てね。
[Laravel6.0 データベース:マイグレーション](https://readouble.com/laravel/6.0/ja/migrations.html)

物理名は項目名とかカラム名とかいうやつ。好きに決めてくれたまえ。
とりあえず適当に作ってみたよ。

```php
public function up()
    {
        Schema::create('admin', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('admin_code');
            $table->string('name');
            $table->sritng('password');
            $table->sritng('role');
            $table->timestamps();
        });
    }
```

usersテーブルに似ているって？気にするな。

これでartisanでmigrateすると、テーブルをクリエイトしてくれる。

```
$php artisan migrate
```

直接テーブルを確認したいときは、MySQL立ち上げて、普通にコマンドで見てください。
ユーザー、パスワードは、.envに設定したものです。

##クラスを作成する
laravelではEloquent（「エロクエント」と読みます）という機能を使ってモデルクラスを作成できる。
これもartisanコマンドで作成できる。

```
$php artisan make::model [クラス名]
```

例えばこんな感じ。

```
$php artisan make:model Admin
```

そうすると、以下のようなガラが作成される。

```php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Admin extends Model
{
    //
}
```

で、この中に何書くの？JavaのMVCみたいに、settergetter書いていけばいい？
Eloquentはsetter/getterイメージの処理だけでなく、いろんな設定が書けます。
例えば
・DBの接続方法
・テーブルの関連付け
　初期設定ではクラス名を複数形にしたテーブルと単数形の名称のクラスを紐づけることになっている（例：usersテーブル→User.php）。今回のテーブル名はAdminで、複数形にしづらかったので個別にテーブル名を設定する。
・タイムスタンプの更新要否の設定
・主キーの設定
・更新可能な項目の設定/更新不可の項目の設定
など、いろいろ定義できます。

テーブルの関連付けと更新可能な項目の設定をした例がこちら。

```php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Admin extends Model
{
    // テーブルの関連付け
    protected $table = 'admin';
    // 更新可能な項目の設定
    protected $fillable = [
        'admin_code',
        'name',
        'password',
        'role'
    ];
}
```

#テストデータを入れる
laravelではデータ投入をシーダーという仕組みで自動化できる仕組みがあります。
入れ方は、以下のバリエーションがある。
・シーダーだけでロジックを組んでデータを投入する。
・シーダー＋Fakerでデータを作成してデータを投入する。
・seeder+FakerにFactoryをつけて、データを投入する。
なんで最後だけ全部英語かって？気にするな。

seederがデータを登録する大元、Fakerが登録するデータを生成するところ、Factoryはseederから呼び出されてテスト項目を作成する処理、というイメージになります。

##Factoryを作る
テストデータの作成はシーダーの中に直接データ作成ロジックを書くこともできるが、今回はファクトリークラスを作成してファクトリークラスでテストデータを作成するようにします。
ファクトリークラスも例によってartisanコマンドで作成します。

```
$php artisan make:Factory [クラス名]
```

今回の例だとこんな感じ。

```
$php artisan make:Factory AdminFactory
```

そうすると、以下のようなガラが作成される。

```php
<?php

/** @var \Illuminate\Database\Eloquent\Factory $factory */

use App\Model;
use Faker\Generator as Faker;

$factory->define(Model::class, function (Faker $faker) {
    return [
        //
    ];
});
```

このガラに、Fakerを使ってデータを設定する処理を書いていく。
例えばこんな感じ。

```php
$factory->define(App\Admin::class, function (Faker $faker) {
    // 現在時刻を取得
    $date = \Carbon\Carbon::now();
    return [
        // データをセット
        'admin_code' => $faker->randomNumber(),
        'name' => $faker->name,
        'password' => $faker->password,
        'role' => $faker->randomDigitNotNull
    ];
});
```

尚、名前などのデータを日本語にしたいときは、config/app.php内にある「faker_locale」設定を日本語に変える。

```php:app.php
/*
|--------------------------------------------------------------------------
| Faker Locale
|--------------------------------------------------------------------------
|
| This locale will be used by the Faker PHP library when generating fake
| data for your database seeds. For example, this will be used to get
| localized telephone numbers, street address information and more.
|
*/

'faker_locale' => 'ja_JP',
```

##seederを作る
seederもartisanコマンドで作成する。

```
$php artisan make:seeder [ファイル名]
```

コマンドを実行すると、/database/seederにseederクラスが作成される。
中身はこんな感じ。相変わらず空だね。

```php
<?php

use Illuminate\Database\Seeder;

class AdminTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        //
    }
}
```

function run()の中に、Factoryクラスを記述する。

```php:AdminTableSeeder.php
public function run()
{
    factory(\App\Admin::class, 10)->create();    
}
```

##DatabaseSeeder.phpの更新
シーダーを使うには、/database/seedsにあるDatabaseSeeder.phpの中に、作成したシーダークラスを定義しなければならない。
定義を追加すると、こんな感じ。

```php:DatabaseSeeder.php
public function run()
{
    $this->call(AdminTableSeeder::class);
}
```

#実行する
ここまで作ったら、artisanコマンドでシーダーを動かす。

```
$php artisan db:seed
```

特定のテーブルのみデータを作成したいときは、--classオプションをつける。
今回の例だと、こんな感じ。

```
$php artisan db:seed --class=AdminTableSeeder
```

これを実行すると、Adminテーブルの中に適当なデータが作成される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/799434cf-f9ff-734d-d742-6f6c3dd0a3b1.png)

これを作っておけば、何万件でもテストデータが作れるね。