FactoryとFakerを利用して、モデルデータを生成してみます。テストやSeederでモデルデータを利用したいときに便利です。
目次
Fakerでダミーデータ生成
まずは、Fakerを利用します。Fakerはデフォルトでcomposer.json
に指定されており、ダミーデータを生成するために利用します。
動作確認
実際にFakerを利用してみます。Laravelのルーティングファイルに以下処理を記述します。
Route::get('/', function () {
$faker = Faker\Factory::create('ja_JP');
$dummyData = [
'name' => $faker->name,
'password' => $faker->password,
'country' => $faker->country,
'prefecture' => $faker->prefecture,
'city' => $faker->city,
'postcode' => $faker->postcode,
'address' => $faker->address,
'streetAddress' => $faker->streetAddress,
'phoneNumber' => $faker->phoneNumber,
'email' => $faker->email,
'safeEmail' => $faker->safeEmail, // (実在しないアドレスのため処理とかで使っても安心)
'company' => $faker->company,
'iso8601' => $faker->iso8601($max = 'now'),
'dateTimeBetween' => $faker->dateTimeBetween($startDate = '-110 years', $endDate = 'now')->format('Y年m月d日'),
'numberBetween' => $faker->numberBetween($min = 100, $max = 200),
'title' => $faker->title,
'realText' => $faker->realText($maxNbChars = 50, $indexSize = 2),
'randomNumber' => $faker->randomNumber($nbDigits = 5),
'randomFloat' => $faker->randomFloat($nbMaxDecimals = 4, $min = 0, $max = 5),
'randomElement' => $faker->randomElement($array = ['男性', '女性']),
'lexify' => $faker->lexify($string = '??????'),
'hexcolor' => $faker->hexcolor,
'ipv4' => $faker->ipv4,
'url' => $faker->url,
'imageUrl' => $faker->imageUrl($width = 640, $height = 480, $category = 'cats', $randomize = true, $word = null),
'userAgent' => $faker->userAgent,
'creditCardType' => $faker->creditCardType,
'creditCardNumber' => $faker->creditCardNumber,
'creditCardExpirationDate' => $faker->creditCardExpirationDate,
'isbn13' => $faker->isbn13,
'isbn10' => $faker->isbn10
];
var_dump($dummyData);
exit();
});
array (size=31)
'name' => string '中津川 翼' (length=13)
'password' => string '$OP(vf:~' (length=8)
'country' => string 'ハード島とマクドナルド諸島' (length=39)
'prefecture' => string '愛知県' (length=9)
'city' => string '高橋市' (length=9)
'postcode' => string '4578842' (length=7)
'address' => string '8904517 島根県中村市南区小林町三宅7-8-10 コーポ加納102号' (length=76)
'streetAddress' => string '吉本町山本5-1-3' (length=20)
'phoneNumber' => string '041-962-0940' (length=12)
'email' => string 'yoshimoto.akira@mail.goo.ne.jp' (length=30)
'safeEmail' => string 'akira.yoshimoto@example.com' (length=27)
'company' => string '株式会社 若松' (length=19)
'iso8601' => string '1996-09-05T04:41:39+0900' (length=24)
'dateTimeBetween' => string '1950年03月07日' (length=17)
'numberBetween' => int 200
'title' => string 'Prof.' (length=5)
'realText' => string 'って見えるやかせいに列れつの電燈でんといました。その上ではねをきちっとありました。私どもジョバンニ。' (length=150)
'randomNumber' => int 44582
'randomFloat' => float 1.3738
'randomElement' => string '男性' (length=6)
'lexify' => string 'mxjlzi' (length=6)
'hexcolor' => string '#c84a8d' (length=7)
'ipv4' => string '255.14.144.130' (length=14)
'url' => string 'http://nagisa.com/' (length=18)
'imageUrl' => string 'https://lorempixel.com/640/480/cats/?80273' (length=42)
'userAgent' => string 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/5361 (KHTML, like Gecko) Chrome/40.0.806.0 Mobile Safari/5361' (length=105)
'creditCardType' => string 'MasterCard' (length=10)
'creditCardNumber' => string '6011044698805423' (length=16)
'creditCardExpirationDate' =>
object(DateTime)[806]
public 'date' => string '2019-10-16 15:40:53.000000' (length=26)
public 'timezone_type' => int 3
public 'timezone' => string 'Asia/Tokyo' (length=10)
'isbn13' => string '9789404568828' (length=13)
'isbn10' => string '1271795167' (length=10)
Fakerの詳しい使い方などは、以下で確認できます。
→ https://github.com/fzaninotto/Faker
ファクトリーでモデルデータ生成
次にファクトリーを利用してみます。
前準備
まず動作確認用に準備を行います。ここでは、usersテーブル
とcountriesテーブル
を作成して動作確認します。
マイグレーションファイル作成
class EloquentTest extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('countries', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->unsignedInteger('country_id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('users');
Schema::drop('countries');
}
}
マイグレーション実行
php artisan migrate
モデル作成
php artisan make:model User
php artisan make:model Country
FakerGeneratorが生成するインスタンスのlocaleをjpにする
App\Providers\AppServiceProvider
に追記します。
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Faker\Generator as FakerGenerator; // 追記
use Faker\Factory as FakerFactory; // 追記
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
//
}
/**
* Register any application services.
*
* @return void
*/
public function register()
{
// 追記
$this->app->singleton(FakerGenerator::class, function () {
return FakerFactory::create('ja_JP');
});
}
}
ファクトリーモデルを定義
database/factories/ModelFactory.php
でファクトリーモデルの定義を行います。
$factory->define(App\Country::class, function (Faker\Generator $faker) {
return [
'name' => $faker->country,
];
});
$factory->define(App\User::class, function (Faker\Generator $faker) {
$countries = App\Country::pluck('id')->all();
return [
'name' => $faker->name,
'country_id' => $faker->randomElement($countries),
];
});
※参考
https://readouble.com/laravel/5.4/ja/database-testing.html#writing-factories
ファクトリーの使用例
テストなどで以下のように利用できます。
// モデル生成のみ。データベースには保存しない。
$user = factory(App\User::class)->make();
// モデル生成して、データベースにも保存する。
$user = factory(App\User::class)->create();
// name属性をオーバーライド。他の属性は定義された通り。
$user = factory(App\User::class)->make([
'name' => 'James',
]);
Seederでファクトリーモデルを利用
Seederファイル生成
php artisan make:seeder SeederCountriesTable
php artisan make:seeder SeederUsersTable
Seeder実装
ファクトリーモデルを利用してSeederを実装します。
class SeederCountriesTable extends Seeder
{
public function run()
{
factory(App\Country::class, 10)->create();
}
}
class SeederUsersTable extends Seeder
{
public function run()
{
factory(App\User::class, 3)->create();
}
}
class DatabaseSeeder extends Seeder
{
public function run()
{
$this->call(SeederCountriesTable::class);
$this->call(SeederUsersTable::class);
}
}
Seeder実行
下記コマンドを実行します。
php artisan db:seed
動作確認
「usersテーブル」と「countriesテーブル」にデータが挿入されていることを確認できました。