テスト環境での機能確認、コードの動作確認を行うためにテーブルに大量のテストデータが必要になる場合があります。手動や自作のプログラムを作ることなく一括で大量のデータを挿入することができると作業の効率化に繋がります。LaravelではSeeding機能を使用することで、大量のダミーデータを一括でテーブルに挿入することが可能です。

Laravel5.7, 5.8で動作確認済み

Seedingの設定について

Laravelでは、usersテーブルへのダミーデータを挿入するSeedingの設定はインストール直後の段階で90%以上完了しています。SeedingについてはLaravelのマニュアルを読んでも最初は混乱するかもしれません。しかし一度usersテーブルを利用してSeedingを実行してみると操作方法をすぐに理解することができます。一度自分の手で実行することがSeedingを理解する上で一番の近道です。

動作確認を行うためには、Laravelのインストールだけではなデータベースとusersテーブルが作成されている必要があります。もしない場合は、sqliteを使うと簡単にテスト環境を構築することができます。

ダミーデータ挿入までの流れ

複数のファイルを触ることになるので、最初は混乱してしまうので先に流れ簡単にまとめておきます。1件のダミーデータの挿入と複数件のダミーデータ一括挿入の差はUserFactory.phpを使うか使わないか違いです。

1件だけのダミーデータ挿入

  1. Seederクラスの作成
  2. UserTableSeederクラスのrunメソッドの更新
  3. DabaseSeedの設定
  4. Seedの実行

複数のダミーデータ一括挿入

  1. Seederクラスの作成
  2. UserTableSeederクラスのrunメソッドの更新
  3. UserFactory.phpファイルの更新
  4. DabaseSeedの設定
  5. Seedの実行

Seederクラスの作成

ダミーデータを作成するためには、ダミーデータを作成するクラスを作成する必要があります。そのクラスのことをLaravelではSeederと呼びます

php artisan make:seederコマンドでSeederの作成を行います。


laravel $ php artisan make:seeder UsersTableSeeder
Seeder created successfully.

make:seederコマンドを実行するとUsersTableSeederクラスがdatabase/seedsディレクトリに作成されます。

seedsディレクトリ

seedsディレクトリ

Seederクラスのrunメソッドの設定

Seederクラスには、insert文を直接記述する方法とUserFactory.phpを呼び出して一括でダミーデータを挿入する方法があります。

1件のデータのみ挿入する場合

UserTableSeederクラスのrunメソッドにデータベースへのinsert文を直接記述します。


use Illuminate\Database\Seeder;

class UsersTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        DB::table('users')->insert([
            'name' => Str::random(10),
            'email' => Str::random(10).'@gmail.com',
            'password' => bcrypt('secret'),
        ]);
    }
}

name, e-mailには、Strクラスのrandomメソッドを利用してその都度ランダムな10桁の文字列を作成しています。passwordはbcrypt関数でsecretの文字列を暗号化しています。nameやe-mailは任意の文字列をハードコーディングすることもできます。

複数のデータを一括挿入

UsersTableSeederクラスのrunメソッドに下記の1行を追加します。この1行を追加することによって、UsersTableSeederのrunメソッドが実行されるとUserテーブルにダミーデータ10件分が挿入されます。10を20に変更すれば20件のデータ挿入になります。


<?php

use Illuminate\Database\Seeder;

class UsersTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $users = factory(App\User::class, 10)->create();
    }
}

上記だけのプログラムではダミーデータに何を入れるのかが設定されていません。Seederではそれらのデータの設定も行うことができます。その設定を行うのが次に説明するUserFactory.phpファイルです。

UserFactory.phpファイルはテンプレートとしてLaravelで事前準備されています。

UserFactory.phpファイル(Model Factory)

※UserTableSeederでinsert文を使用した場合は下記の文章はスキップしてDatabaseSeederの設定に進んでください。

$users = factory(User::class, 10)->create()で実行される処理の内容は、database/factoriesディレクトリにあるUserFactory.phpに記載されています。UserFactory.phpはfakerやランダム関数等を利用して、ダミーのデータを作成するクラスです。このクラスのことをModel Factory(モデルファクトリー)と呼びます。


<?php

use Faker\Generator as Faker;

$factory->define(App\User::class, function (Faker $faker) {
    return [
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'email_verified_at' => now(),
        'password' => '$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', // secret
        'remember_token' => str_random(10),
    ];
});
$faker->nameによってランダムなダミーな名前が付けられます。

DatabaseSeederの設定

作成したUserTableSeederクラスを呼び出すDatabaseSeederの設定を行います。DatabaseSeeder.phpファイルは、database/seedsディレクトリにあります。runメソッドがインストール直後ではコメントアウトされているので、それを外します。


<?php

use Illuminate\Database\Seeder;

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

Seedの実行

ダミーデータを作成するための準備が整ったので、php artisan db:seedコマンドを実行します。コマンド実行後にプログラムに誤りがなければUsersTableSeederが実行され、seedingが成功しているメッセージが表示されます。


laravel $ php artisan db:seed
Seeding: UsersTableSeeder
Database seeding completed successfully.
php artisan db:seedを実行後、ReflectionException : Class UsersTableSeeder does not existのエラーが出た場合は、composer dump-autoloadを実行してください。

テーブルを再作成する際にダミーデータを挿入することもできます。その場合は、php artisan migrate:refreshコマンドに–seedをつけて実行します。refreshコマンドは一度すべてのテーブルを削除するのでテスト環境でのみ実行してください。本番環境で実行するとこれまでに保存してデータも削除されます。


laravel $ php artisan migrate:refresh --seed
Rolling back: 2014_10_12_100000_create_password_resets_table
Rolled back:  2014_10_12_100000_create_password_resets_table
Rolling back: 2014_10_12_000000_create_users_table
Rolled back:  2014_10_12_000000_create_users_table
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table
Seeding: UsersTableSeeder
Database seeding completed successfully.

Seedingの一連の流れ

php artisan db:seedを実行するSeedingに関連するファイルを図にすると下記となります。

本文書で利用したファイルは、DatabaseSeeder.php、UserTableSeeder.php, UserFactory.phpの3つのファイルです。userテーブルだけではなく、他のテーブル(例えばpostテーブル)にもダミーデータを挿入したい場合は、PostTableSedder.phpやPostFactory.phpを作成し、DatabaseSeeder.phpからPostTableSeeder.phpを呼び出すことで行うことができます。

Seedingの流れ

Seedingの流れ

UserTableSeeder.phpにinsert文を記述した場合はFactory(UserFactory.php)は必要ありません。

リレーションのあるテーブルへの挿入

ここまでの説明で1つのテーブルへのデータ挿入の確認を行うことができました。次にテーブル間で1対多のリレーションがある場合の設定について説明を行っていきます。

postsテーブルの作成

例としてblogの記事を登録するpostsテーブルを作成します。blogの記事にはだれがその記事を作成したかテーブルの中に保存する必要があります。blogでは一人のユーザが複数の記事を書くのでテーブルの関連を図に表すと下記のようになります。この関係をデータベースではone to manyリレーションシップといいます。

usersとpostsテーブルの関係
usersとpostsテーブルの関係

次にpostsテーブルはマイグレーションファイルを利用して作成します。make:modelコマンドを実行するとappディレクトリの下にPost.phpファイル、database¥migrationsテーブルの下にpostテーブルのマイグレーションファイルが作成されます。


$ php artisan make:model Post -m

マイグレーションファイルに作成するテーブルの列情報を記述します。user_id列にusersテーブルのidを保存するためにpostsテーブルにはuser_idの列を作成します。


public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->unsignedInteger('user_id');
        $table->string('title');
        $table->text('content');
        $table->timestamps();
    });
}

Seederクラスの作成

postsテーブル用のseederクラスの作成を行います。


$ php artisan make:seeder PostsTableSeeder
Seeder created successfully.

Seederでは10件分をデータを一括で挿入する設定を行います。


<?php

use Illuminate\Database\Seeder;

class PostsTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $posts = factory(App\Post::class, 10)->create();
    }
}

Factoryファイルの作成

usersテーブルのFactoryファイルはLaravelのインスールで事前に作成されていましたが、postsテーブルの場合はFactoryファイルを作成する必要があります。作成は下記のコマンドmake:factoryで行います。


$ php artisan make:factory PostFactory -m Post
Factory created successfully.
-mでPostを指定しないと作成されるPostFactory.phpの中のPostの文字列がModelとして作成されます。

database¥factoriesの下にPostFactory.phpが作成されるので下記のように作成するダミーデータに関する設定を行います。ポイントはuser_idにUserのFactoryを使用してuserのデータも同時に作成を行っています。


<?php

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

use App\Post;
use Faker\Generator as Faker;

$factory->define(Post::class, function (Faker $faker) {
    return [
        'title' => $faker->title,
        'content' => $faker->paragraph,
        'user_id' => function () {
            return factory(App\User::class)->create()->id;
        }
    ];
});

これで1対多のリレーションを持ったテーブルへのデータ挿入ができました。

DatabaseSeederの設定

最後にdatabase¥seeds¥DatabaseSeeders.phpファイルを下記のように変更します。


    public function run()
    {
        $this->call(PostsTableSeeder::class);
    }

Seederの実行

postsテーブルへのダミーデータ一括登録の準備が整ったので、seederを実行します。メッセージにDatabase seeding completed successfully.が表示されればテーブルへのデータ登録は完了しています。


env_test $ php artisan db:seed
Seeding: PostsTableSeeder
Database seeding completed successfully.

ダミーデータが作成されたかの確認

Usersテーブルにダミーデータが10件登録されているのか確認してみましょう。php artisan tinkerを使用します。データが表示されれば、Seedingの処理は成功です。


laravel $ php artisan tinker
Psy Shell v0.9.9 (PHP 7.1.16 — cli) by Justin Hileman
>>> $users = App\User::all();
=> Illuminate\Database\Eloquent\Collection {#2928
     all: [
       App\User {#2929
         id: "1",
         name: "Ms. Victoria Auer",
         email: "lbradtke@example.net",
         email_verified_at: "2018-12-19 07:33:11",
         created_at: "2018-12-19 07:33:11",
         updated_at: "2018-12-19 07:33:11",
       },

idを1を持つUserのデータを取得したい場合は、App\User::find(1)を実行すると取得することができます。

付録

日本語のダミーデータ作成

ダミーで作成されていたユーザ名はすべて英語になっていましたが、日本語に変更することもできます。

config/app.phpファイル内にfaker_localeを設定する箇所があるので、ja_JPに変更すると日本語になります。

php artisan tinkerを使用してダミーデータ作成

UserFactory.phpファイルの作成が完了していたら、php artisan tinkerからダミーデータを作成することが可能です。


$ php artisan tinker
Psy Shell v0.9.9 (PHP 7.1.23 — cli) by Justin Hileman
>>> factory('App\User',10)->create();
=> Illuminate\Database\Eloquent\Collection {#2997
     all: [
       App\User {#2993
         name: "田中 淳",
         email: "naoko22@example.net",
         email_verified_at: "2019-06-12 05:22:10",
         updated_at: "2019-06-12 05:22:10",
         created_at: "2019-06-12 05:22:10",
         id: 1,

   }

まとめ

ここまでの読み進めた方はuserテーブルへのダミーデータへの挿入は簡単にできるようになったかと思います。今回は単独テーブルでのデータ挿入でしたが、次回は関連のある複数のテーブルでのSeedingについて説明を行いたいと思います。