今回はLaravelのfactory機能を使って、ダミーデータを作成したり、中間テーブルにデータを挿入したりします。
ぶっちゃけ、そこまで難しくありません。
ざっくりしたファクトリーを使用する手順は、
1.ファクトリーを作って、テーブルに挿入するデータのルールを記述する。
2.シーダーを作って、実際にデータを挿入する処理を記述する。
3.作ったシーダーをコマンドで実行できるように登録する。
これだけです。
今回は、novelsテーブル(小説)
とtagsテーブル(タグ)
の中間テーブルnovel_tagテーブル
にデータを挿入する設定です。
また、最大で6つまで小説にタグを設定できるという仮定で進めていきます。
それではガンガンやっていきましょう。
##1.ファクトリーを作って、テーブルに挿入するデータのルールを記述する。
まずはnovelsテーブル(小説)
とtagsテーブル(タグ)
用のファクトリーを作成します。
下記コマンドを実行してください。
php artisan make:factory NovelFactory
php artisan make:factory TagFactory
これで、app > database > factories
直下にNovelFactory.php
とTagFactory.php
が作成されているはず。
それぞれに下記の記述を追加します。
<?php
use App\Model;
use Faker\Generator as Faker;
$factory->define(App\Novel::class, function (Faker $faker) {
//Usersテーブルの中からランダムに1つのレコードのidを取得する。
$user_id = App\User::all()->random(1)[0]->id;
return [
'title'=>$faker->word,
'summary'=>$faker->sentence,
'user_id'=>$user_id,
];
});
<?php
use App\Model;
use Faker\Generator as Faker;
$factory->define(App\Tag::class, function (Faker $faker) {
return [
'name'=>$faker->word,
];
});
簡単に解説しておきます。
まずFactoryを使う時は$factory->define(App\Novel::class, function (Faker $faker) {ココ});
の中にコードを記述します。
$user_id = App\User::all()->random(1)[0]->id;
こちらのコードはUsersテーブルからランダムで1つのレコードを取得。そして、そのレコードのidを取得しています。
randomメソッド
を使えば、引数に与えた数値の数だけ、コレクションの中からインスタンスを取得することができます。
ここで取得したusersテーブルのid
を'user_id'=>$user_id,
で外部キーを実現しています。
##2.シーダーを作って、実際にデータを挿入する処理を記述する。
次にシーダーを作成します。
php artisan make:seed NovelsTableSeeder
php artisan make:seed TagsTableSeeder
これでapp > database > seeds
の中にNovelsTableSeeder.php
とTagsTableSeeder.php
ができているはず。
こちらのファイルを下記のように変更します。
<?php
use Illuminate\Database\Seeder;
use App\Tag;
use App\User;
class NovelsTableSeeder extends Seeder
{
public function run()
{
$tags = Tag::all();
// factoryを利用
factory(App\Novel::class, 100)
->create()
->each(function (App\Novel $novel) use ($tags) {
//1~6までの数値をランダムで取得
$ran = rand(1, 6);
// 中間テーブルに紐付け
$novel->tags()->attach(
//tagsテーブルからランダムで1~6個のインスタンスを紐づける。
$tags->random($ran)->pluck('id')->toArray(),
//attachの第二引数は他のカラムに挿入したい値を入れることができる。
//今回はtag_numberというカラムにランダムで1~6の数値を挿入。これは僕の都合上やってるだけなので、気にしなくてOK。
['tag_number'=>$ran]
);
});
}
}
<?php
use Illuminate\Database\Seeder;
class TagsTableSeeder extends Seeder
{
public function run()
{
factory(App\Tag::class, 50)->create();
}
}
上記の通りです。
多対多の中間テーブルへの紐付けはattachメソッド
を使うのが基本です。
第一引数に紐づけるid、第二引数には他のカラムにも値を追加したい場合はその値を指定します。
今回の場合は$novel->tags()->attach
とすることで、中間テーブルのnovel_idカラム
に$novelのid
が保存されます。次にtag_idカラム
の値を指定する必要があるので、attachメソッド
内に記述します。
$tags->random($ran)->pluck('id')->toArray(),
$tags
には$tags = Tag::all();
で取得したtagsテーブルの全データが入っています。その中からランダムで1~6個のインスタンスを取得して、それらのidを配列にしています。$ran
は$ran = rand(1, 6);
の部分でランダムで1~6の値を挿入しています。
このようにしているのは、小説には1~6個までのタグを指定できるという設定にしているからです。
別に1つしかタグ付けしないなら、下記でOK。
$tags->random(1)->value('id'),
##3.作ったシーダーをコマンドで実行できるように登録する。
最後にapp > database > seeds > DatabaseSeeder.php
にて、今作ったシーダーを登録します。
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
public function run()
{
$this->call([
TagsTableSeeder::class, //先にコッチ。
NovelsTableSeeder::class,
]);
}
}
先にタグのシーダーを記述しておかないとエラーになるので注意してください。
あとは下記コマンドを実行すればOkです。
php artisan db:seed
駆け足でしたが、これにて終了です。
factoryを使えば簡単に大量のデータを作れます。
慣れないうちは大変だと思いますが、ぜひ使ってみてください。