6 Tips About Data Seeding in Laravel

Laravel migration mechanism has a great function of seeding data. In this article, I will show random tips from my own experience, how to use seeding in real-life cases.


Tip 1. Use updateOrCreate() to avoid double-seeding

Imagine this seeder code, and imagine if for some reason this seeder would be launched more than once:

public function run()
{
    $items = [
        ['id' => 1, 'title' => 'Administrator'],
        ['id' => 2, 'title' => 'Simple user'],
    ];

    foreach ($items as $item) {
        Role::create($item);
    }
}

Second attempt to run seeder would probably fail because of conflicting IDs. In other scenario, if you don't specify IDs, then you may end up with too much data in the table, with repeating entries. To avoid that, do this:

foreach ($items as $item) {
    Role::updateOrCreate(['id' => $item['id']], $item);
}

Some more details in my other article.


Tip 2. Run only one Seeder class

Some time ago I was quite surprised by how many people don't know that you can specify a seeder class when running php artisan db:seed.

php artisan db:seed

This command above will launch everything listed in DatabaseSeeder.php file.

But you can limit the launch to one exact seeder:

php artisan db:seed --class=UsersTableSeeder

Tip 3. Run Seeder Class From Migration

Quite often you need to create a new DB table and immediately seed it with some data. But in production environment you can't just run "artisan db:seed", especially if you have automated deployment setup which involves only "artisan migrate" command.

The trick is to launch a specific seeder from migration file itself.

public function up()
{
    Schema::create('themes', function (Blueprint $table) {
        $table->increments('id');
        $table->text('name');
    });

    Artisan::call('db:seed', [
        '--class' => ThemesTableSeeder::class
    ]);
}

Tip 4. Seeder Factory with Relationship: Use Parent's Factory

If you use Factories for your seeds, how do you set up relationships between two models? For example, you need to seed 10 companies and 10 contacts within those companies?

Here's how database/factories/CompanyFactory.php may look like:

$factory->define(App\Contact::class, function (Faker\Generator $faker) {
    return [
        'company_id' => factory('App\Company')->create()->id,
        'first_name' => $faker->firstName(),
        'last_name' => $faker->lastName,
        'phone1' => $faker->phoneNumber,
        'phone2' => $faker->phoneNumber,
        'email' => $faker->email,
        'skype' => $faker->word,
        'address' => $faker->address,
    ];
});

See how company_id field is filled in? With another factory.

There's also another, perhaps less popular way - read about it in my another article.


Tip 5. DatabaseSeeder for Local and Production

Sometimes you need to seed some data only in your local environment, but not in production. Or, use different seeder files for different environments.

Not sure if it's the most elegant way, but here's how in the past I've achieved different seeding for local and production environments.

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        if (app()->environment() == 'production') {
            $this->call(ThemesTableSeeder::class);
            $this->call(LanguagesTableSeeder::class);
        } else {
            $this->call(UsersTableSeeder::class);
            $this->call(ModulesTableSeeder::class);
            $this->call(ThemesTableSeeder::class);
            $this->call(LanguagesTableSeeder::class);
        }
    }
}

Tip 6. Use iSeed to Generate Seeders from Database

Final tip is actually a tool I've used myself quite a few time, it's called iSeed Generator.

Here's my video about it:


That's it. Final "general" tip would be to form your seeders in a way that on your local/staging environments you could run "artisan migrate:fresh --seed" safely multiple times, without losing any important data, but on production environment you need to run "artisan db:seed" only once, and then forget about seeders. If you need to run some seed on production, put it in migration, see Tip 3.

Would you add any more tips about seeding in Laravel?

No comments or questions yet...

Like our articles?

Become a Premium Member for $129/year or $29/month
What else you will get:
  • 22 courses (477 lessons, total 38 h 20 min)
  • 2 long-form tutorials (one new every week)
  • access to project repositories
  • access to private Discord