DB
Eloquent
factory
laravel5.4

Laravelでfactoryを使い初期データを作成する基本的な方法(リレーション有り)

前提

・掲示板のようなサービスを想定

・users、threads、repliesテーブルが存在する
(テーブル構成は割愛)
・User:Thread => 1対多
・User:Reply => 1対多
・Thread:Reply => 1対多

・threadsテーブルにはuser_id
・repliesテーブルにはuser_id、thread_id
がある

ソースコード

①まずはfakerを使ってModelFactoryの定義

//ModelFactory.php

//User
$factory->define(App\User::class, function (Faker\Generator $faker) {
    static $password;

    return [
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'password' => $password ?: $password = bcrypt('secret'),
        'remember_token' => str_random(10),
    ];
});

//Thread
$factory->define(App\Thread::class,function($faker){
    return [
        'user_id' => function(){
            //Thereadインスタンスを作成する際に、リレーションするUserインスタンスも生成する
            return factory(App\User::class)->create()->id;
        },
        'title' => $faker->sentence,
        'body' => $faker->paragraph,

    ];
});

//Reply
$factory->define(App\Reply::class,function($faker){
    return [
        'thread_id' => function(){
            //Thereadインスタンスを作成する際に、リレーションするUserインスタンスも生成する
            return factory(App\Thread::class)->create()->id;
        },  
        'user_id' => function(){
            //Thereadインスタンスを作成する際に、リレーションするUserインスタンスも生成する
            return factory(App\User::class)->create()->id;
        },
        'body' => $faker->paragraph,

    ];
});

②threadsテーブルの初期データ作成

先ほどのModelFactory.phpにて、Threadインスタンスを生成する際にUserインスタンスも生成するよう定義しているので、以下のコードだけで、threadsテーブルとusersテーブルに50件のデータが入る

$threads = factory('App\Thread',50)->create();

③repliesテーブルの初期データ作成

Thread1件に対して10件のReplyがあると想定
先ほど生成した50件のThread一つ一つに対応するReplyを10件ずつ作成する
factoryで複数件生成する場合はインスタンスのコレクションが返って来るため、each()を使うことで、一つ一つのインスタンスに対して処理を行える

$threads->each(function($thread){//クロージャ内で$threadを使うため、引数に渡している
   factory('App\Reply',10)->create(['thread_id' => $thread->id]);
})

クロージャの中でcreate(['thread_id' => $thread->id])とすることで、
生成されるReplyインスタンスのthread_id属性をオーバーライド出来る。
(repliesテーブルのthread_idをthreadsテーブルのidと同一に出来る)

ちなみに、上記全て英語のLaracasts.com + 日本語readouble.comを交互に見ながら理解しました。英語の学習素材は避けがちですが、動画であれば意外といけることが判明。

以上。