これは何
LaravelのSeederでDB書き込みだけじゃなくて、ダミーの画像投稿ができたので記録です。
背景
ファイルダウンロードリンクのテストのために、ファイルアップロードをしておく必要がありました。今やっているプロジェクトではSeederでDBの中身を作成していましたが、画像実体はストレージに入れていなかったのでSeederを流した直後に画像ダウンロードを試すことができませんでした。
これまでにPHPUnitでのテストで画像アップロードはやっていたので、テストを流した後にダウンロードを試せましたが、ちょっと面倒なので最初から入っていて欲しいという気持ち。
やり方
Faker はこちら https://github.com/fzaninotto/Faker
composer require fzaninotto/faker --dev
とかでインストールして使用する。
FileFactory.php を作成してアップロードする方法を定義しておく
<?php
use Faker\Generator as Faker;
use Illuminate\Http\UploadedFile;
$factory->define(Infra\EloquentModel\File::class, function (Faker $faker) {
// ファイル実体の保存
$fileRealPath = UploadedFile::fake()->create('tempfilename.pdf', 10)->store('private/files');
return [
'original_name' => $faker->unique()->realText(10),
'content_type' => 'application/pdf',
'storage_type' => 'local',
'path' => $fileRealPath
];
});
DocumentFactory.php はFileFactoryを使用するやつ。DocumentSeederからFileFactoryを直接呼び出してもいいが、繰り返しSeederに同じコードを書かないために間に噛ませている。
<?php
use Faker\Generator as Faker;
$factory->define(\Infra\EloquentModel\Document::class, function (Faker $faker) {
return [
'file_id' => function () {
// 上のFileFactoryで設定したものを呼び出し。ここらのid()を呼び出すコードは環境によって全然違うと思うのでよしなに
return factory(\Infra\EloquentModel\File::class)->create()->toDomain()->id();
},
'title' => $faker->unique()->realText(20)
];
});
SeederでFactoryを呼び出して実際にファイル作成保存とDB保存
<?php
use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Factory as Factory;
class DocumentSeeder extends Seeder
{
public function run(Factory $factory)
{
// 登録したFactoryをofで呼び出し
$factory->of(\Infra\EloquentModel\Document::class)->times(1)->create();
}
}
DatabaseSeederからDocumentSeederの呼び出しも忘れずに
public function run()
{
$this->call(DocumentSeeder::class);
}
あとは artisan migrate:fresh --seed
でもやって適用(freshはDropテーブルするのでLocal環境以外で実行するときにはお気をつけて)