PHP

Seeding Laravel with Relationships and Media

Library with Media

You Need Data for Development and Testing

Your Laravel project has a database, you just started development and you want to fill it with data.

Write a Database Seeder

The textbook approach is to write a factory to generate instances of the class using Faker for faking values. Like,

OrderFactory.php


$factory->define(App\Order::class, function (Faker\Generator $faker) {
	return [      
	    'price' => $faker->randomNumber(8),
	    'num' => $faker->numberBetween(1, 50),
	    'total' => $faker->randomNumber(8),
	    'fee' => $faker->randomNumber(5),
	    'type' => $faker->randomElement(['1', '2']),
	];
});

And then a seeder, one for each class, that uses the factory. Such as:

OrdersTableSeeder.php

use Illuminate\Database\Seeder;

class OrdersTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        factory(App\Order::class, 100)->create();
    }
}

Handling Relationships

While seeding one class, you need to generate a reference to an instance in another class that is also being generated. The best approach that we found is to randomly generate a reference based on knowing how many instances of the referenced class are going to be generated.

If the Order class references the Product class, and we know the seeder of the later is going to generate 300 instances, then we generate the reference field of the Order as a number between 1 and 300. Such as:


'product_id' => $faker->numberBetween(1, 300),

in OrderFactory.php.

Seeding Media

We have a Product model where each product has an image. We use the Laravel Media Library to manage our images.

We seed the Product model with media from a given fixed set of images. The folder original contains our initial set of images. The seeder for the model Product will randomly pick an image from that folder and assign it to the product.

ProductsTableSeeder.php


use Illuminate\Database\Seeder;

class ProductsTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {

	    factory(App\Product::class, 300)->create()->each(function ($p) {        

	        $num_originals = 9;
	        $original_files_folder = 'originals/';

	        // randomly select an image
	        $pathToFile = $original_files_folder . random_int(1, $num_originals) . '.jpg';

	        // add it to the product through the media library
	        $p->addMedia($pathToFile)->preservingOriginal()->toMediaCollection('product', 'product');

	    });
	  }
}

Yoram Kornatzky

Yoram Kornatzky