Laravel6.x, Laravel5.8, 5.7で動作確認済み

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

Seedingの設定について

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

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

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

ダミーデータの挿入方法には1件のみ挿入する方法と一括挿入する方法があります。処理の違いは、UserFactory.phpを使うか使わないかの違いです。1件のデータ挿入は効率化には繋がりませんが、説明は行なっておきます。

usersテーブルの場合は、Laravel側で事前に設定がなされているのでダミーデータを挿入する場合処理は数秒で完了しますが複数のファイルを利用することになるので混乱しないように先に流れを簡単にまとめておきます。

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)

1件のデータのみ挿入する場合を選択し、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(User::class, function (Faker $faker) {
    return [
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'email_verified_at' => now(),
        'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
        'remember_token' => Str::random(10),
    ];
});
$faker->nameによってランダムなダミーな名前が付けられます。Laravel5.xではパスワードがsecretでしたがLaravel6.xではpasswordになっています。

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を実行してください。
usersテーブルが存在していない場合は、Illuminate\Database\QueryException : SQLSTATE[HY000]: General error: 1 no such table: usersのエラーが発生します。その場合は、php artisan migrateコマンドでusersテーブルを作成してください。テーブルを作成するためには事前にデータベースの作成も必要です。

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


$ php artisan migrate:refresh --seed
Rolling back: 2019_08_19_000000_create_failed_jobs_table
Rolled back:  2019_08_19_000000_create_failed_jobs_table (0.01 seconds)
Rolling back: 2014_10_12_100000_create_password_resets_table
Rolled back:  2014_10_12_100000_create_password_resets_table (0 seconds)
Rolling back: 2014_10_12_000000_create_users_table
Rolled back:  2014_10_12_000000_create_users_table (0 seconds)
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (0 seconds)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (0 seconds)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated:  2019_08_19_000000_create_failed_jobs_table (0 seconds)
Seeding: UsersTableSeeder
Seeded:  UsersTableSeeder (0.15 seconds)
Database seeding completed successfully.
Laravel6.xではfailed_jobsテーブルが追加されています。Laravel5.xではfailed_jobsのマイグレーション情報は表示されません。

データが挿入されたかどうか確認するためにtinkerを利用します。10件分のユーザ情報が表示されればSeedingは正常に動作しています。


$ php artisan tinker
Psy Shell v0.9.9 (PHP 7.2.21 — cli) by Justin Hileman
>>> $user = App\User::all();
=> Illuminate\Database\Eloquent\Collection {#3012
     all: [
       App\User {#3013
         id: "1",
         name: "Miss Mathilde Buckridge V",
         email: "arnaldo.prohaska@example.com",
         email_verified_at: "2019-10-23 05:14:25",
         created_at: "2019-10-23 05:14:25",
         updated_at: "2019-10-23 05:14:25",

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文を記述した場合(1件だけダミーデータを挿入)はFactory(UserFactory.php)は必要ありません。

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

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

postsテーブルの作成

例としてブログの記事を登録するpostsテーブルを作成します。ブログの記事にはだれがその記事を作成したかテーブルの中に保存する必要があります。ブログでは一人のユーザが複数の記事を書くのでテーブルの関連を図に表すと下記のようになります。この関係をデータベースでは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();
    });
}

マイグレーションファイルが作成できたら、php artisan mirgateコマンドを使ってpostsテーブルの作成を行います。


$ php artisan migrate
Migrating: 2019_10_23_053953_create_posts_table
Migrated:  2019_10_23_053953_create_posts_table (0 seconds)

Seederクラスの作成

postsテーブル用のseederクラスの作成を行います。実行するとdatabase¥seedsディレクトリにPostsTableSeeder.phpファイルが作成されます。


$ php artisan make:seeder PostsTableSeeder
Seeder created successfully.

PostsTableSeeder.phpファイルでは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に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ファイルを下記のように変更します。userに関するデータ作成はPostFactory.phpで行われているので、UsersTableSeederの設定の行は必要ありません。


    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.

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

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


$ php artisan tinker
Psy Shell v0.9.9 (PHP 7.2.21 — cli) by Justin Hileman
>>> $post = App\Post::all();
=> Illuminate\Database\Eloquent\Collection {#3012
     all: [
       App\Post {#3013
         id: "1",
         user_id: "1",
         title: "Prof.",
         content: "Nam aliquam repudiandae hic eos. Laboriosam ut vero nihil quas. Cumque ullam earum temporibus voluptate. Eaque rerum suscipit ut rerum.",
         created_at: "2019-10-23 05:48:21",
         updated_at: "2019-10-23 05:48:21",
       },

user_idには1が入っているので、App\User::find(1)を実行すると取得することができます。


>>> App\User::find(1);
=> App\User {#2998
     id: "1",
     name: "Marielle Kuhlman",
     email: "schmeler.deion@example.net",
     email_verified_at: "2019-10-23 05:48:21",
     created_at: "2019-10-23 05:48:21",
     updated_at: "2019-10-23 05:48:21",
   }

付録

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

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

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,

   }

その他のダミーデータ

本文書では、users, postsテーブルにダミーデータを挿入するため、name, safeEmail, title, paragraphを利用しました。これ以外にもたくさんのダミーデータが準備されています。他のダミーデータについてはvendor¥fzaninotto¥faker¥src¥Faker¥Generator.phpファイルで確認することができます。

一部紹介しておきます。

  • firstName
  • firatNameMale
  • firstNameFemale
  • lastName
  • title
  • city
  • postcode
  • address
  • country
  • companyEmail
  • colorName

まとめ

ここまでの読み進めた方はuserテーブルへのダミーデータへの挿入とone to manyのリレーショップのあるテーブルへのダミーデータへの挿入は理解できたかと思います。