
九保すこひです(フリーランスのITコンサルタント、エンジニア)
さてさて、これはLaravel
に限らずですがウェブサイトを構築するに当たって多くの場合であると便利だな、というものがあります。
それが、「テストデータ」です。
例えば、テストユーザーを何人か登録しておいてログイン機能をテストしたり、取り扱っている商品のテストデータを作って検索がうまくいくかチェックしてみたりと、テストデータを用意することで開発を効率的にすることができます。
そして、Laravel
ではこのテストデータの作成にはfzaninotto/Fakerという有名パッケージを使っていて、特別何もインストールしなくてもそのまま使えます。
ただし、Faker
は名前や住所などよく使うデータには対応しているものの(しかも日本語OKのものもあります)、やはり独自で作らないといけないものもあります。
そこで!
今回は、Faker
を拡張してテストデータを作成する方法を紹介します。
ぜひ皆さんのお役に立てると嬉しいです
開発環境: Laravel 6.0
目次 [非表示]
やりたいこと
今回は、Faker
を使って「DIYや工具」の商品データを作成します。
※データ取得はYahoo ショッピングの商品検索APIを使うので、カテゴリIDを変更すればお好きな商品に変更することができます。
前提として
上の項目でも書きましたが、今回のコードではYahooショッピングAPI
のデータを使って実装します。そのため、バーコード・スキャナーでIBSNを読み取って本の入荷処理をするの「準備する」を参考にしてClient ID
を取得しておいてください。
そして、取得したClient ID
は以下のように.env
に追加しておいてください。
YAHOO_APPID=(あなたのClient ID)
では実際にコードを書いていきましょう!
商品データのテーブル、モデルを用意する
まずは、テストデータを登録するためのDBテーブルと、その管理をするモデルを作成します。
以下のコマンドを実行してください。
php artisan make:model Product -m
これで、モデルProduct
とproducts
テーブルのマイグレーションが作成されました。
では、作成されたdatabase/migrations/****_**_**_******_create_products_table.php
を開いてup()
を次のように変更しましょう。
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name')->comment('商品名');
$table->string('code')->comment('商品コード');
$table->integer('price')->comment('価格');
$table->timestamps();
});
}
変更が終わったら、マイグレーションを実行してください。
php artisan migrate
実行するとテーブルこのようになります。
Fakerの独自プロバイダーを作成する
専用のServiceProviderをつくる
php artisan make:provider FakerServiceProvider
すると、app/Providers/FakerServiceProvider.php
が作成されるので中身を以下のように変更してください。
<?php
namespace App\Providers;
use App\Faker\Product;
use Faker\Factory as FakerFactory;
use Faker\Generator as FakerGenerator;
use Illuminate\Support\ServiceProvider;
class FakerServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* @return void
*/
public function register()
{
$this->app->singleton(FakerGenerator::class, function ($app) {
$faker = FakerFactory::create($app['config']->get('app.faker_locale', 'en_US'));
$faker->addProvider(new Product($faker));
return $faker;
});
}
/**
* Bootstrap services.
*
* @return void
*/
public function boot()
{
//
}
}
変更したら、このServiceProvider
をLaravel
へ登録します。
'providers' => [
// 省略
App\Providers\FakerServiceProvider::class
],
Faker用の独自クラスをつくる
FakerServiceProvider
ではApp\Faker\Product
というクラスを利用していますが、まだ存在していないので作成していきましょう。
まず、app/Faker/Product.php
というファイルを作成してください。(Faker
フォルダも無いので作成してください)
そして、中身は以下のようにします。
<?php
namespace App\Faker;
use Illuminate\Support\Arr;
class Product extends \Faker\Provider\Base
{
private $_products = [];
public function product($parameters) {
if(empty($this->_products)) {
$this->_products = $this->getProducts($parameters);
}
return Arr::random($this->_products);
}
private function getProducts($parameters) {
$parameters['appid'] = env('YAHOO_APPID');
$url = 'https://shopping.yahooapis.jp/ShoppingWebService/V1/json/itemSearch?'. http_build_query($parameters);
$json = file_get_contents($url);
$data = json_decode($json, true);
$products = [];
$total = intval($data['ResultSet']['totalResultsReturned']);
for($i = 0 ; $i < $total ; $i++) {
$product = $data['ResultSet'][0]['Result'][$i];
$products[] = [
'name' => $product['Name'],
'code' => $product['Code'],
'price' => $product['Price']['_value'],
];
}
return $products;
}
}
やっていることはシンプルで、getProducts()
の中でYahoo API
にアクセスして必要な情報を取得、そして、Arr::random()
でその中からランダムに商品データを返すようにしているだけです。
テストデータを追加してみる
では、ここまででつくったFaker
の独自プロバイダーが使えるかどうかをLaravel
のテストデータ機能Factory
とSeeder
を使って試してみましょう。
Factoryをつくる
まず、Factory
をつくりましょう。
Factory
はテストデータを作成するパッケージFaker
をより使いやすくするためのもので、例えば以下のようにするだけで毎回違うテストデータを用意することが出来るようになります。
factory(App\User::class)->create();
では、以下のコマンドを実行してください。
php artisan make:factory ProductFactory
そして、作成されたdatabase/factories/ProductFactory.php
を開いて$factory->define()
を以下のように変更します。
$factory->define(Product::class, function (Faker $faker) {
$parameters = [
'category_id' => 2503, // DIY、工具,
'hits' => 50 // 50件取得
];
return $faker->product($parameters);
});
Seederをつくる
続いてはSeeder
です。
以下のコマンドでファイルを作成しましょう。
php artisan make:seed ProductsTableSeeder
すると、database/seeds/ProductsTableSeeder.php
が作成されるのでrun()
を以下のように変更します。
public function run()
{
for($i = 0 ; $i < 25 ; $i++) {
factory(\App\Product::class)->create();
}
}
変更が完了したら、ProductsTableSeeder
をLaravel
に登録しておきます。database/seeds/DatabaseSeeder.php
を開いて以下のように追加しておいてください。
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
//$this->call(UsersTableSeeder::class);
$this->call(ProductsTableSeeder::class);
}
}
これで作業は完了です!
実際にテストしてみる
では、ここまでで作成したFactory
とSeeder
を実行してみましょう。
php artisan migrate:fresh --seed
実行結果はこうなりました。
完成です!
ちなみに
ちなみに、今回紹介したYahoo ショッピングAPIは2020年6月30日で終了し、新しいAPIが2019年12月に登場するそうですので、ゆくゆくはコードを変更する必要がでてくると思います。
おわりに
ということで、今回はFaker
を拡張して独自プロバイダーをつくり、テストの商品データが使えるようにしてみました。
実は当初は他のダミーデータ作成サイトからスクレイピングすることも考えましたが、いつまで提供を続けるかが未知数なので今回はYahoo API
を使うことにしました。(といってもそのAPIも・・・「ちなみに」をご覧ください)
ただ、今回のテクニックを使えば独自に好きなバンド名やタレント名、漫画などの登場人物などをテストデータとして使えるようになりますので、開発のモチベーションを少しだけアップさせられるかもしれません。
ぜひ皆さんも活用してみてくださいね。
ではでは〜!