Image for post
Image for post

Seeding is Hard

Chris Kankiewicz
May 24, 2018 · 2 min read

We’ve all been there… banging our heads against a wall for 20 minutes wondering why our app isn’t working before we realize we forgot to seed our database when running migrations. Okay, easy fix:

$ php artisan migrate --seed
Migration table created successfully.
Migrating: 1996_02_27_123456_create_pokemon_table
Migrated: 1996_02_27_123456_create_pokemon_table
Seeding: PokemonSeeder
ReflectionException : Class PokemonSeeder does not exist

Sigh… okay. I should have remembered to refresh the the autoload file first. My bad.

$ composer dump-autoload
$ php artisan migrate --seed
Nothing to migrate.
Seeding: PokemonSeeder
Illuminate\Database\QueryException : SQLSTATE[23000]: Integrity constraint violation: 19 UNIQUE constraint failed: pokemon.id (SQL: insert into "pokemon" ("id", "name", "description") values (25, Pikachu, Whenever Pikachu comes across something new, it blasts it with a jolt of electricity.))

(╯°□°)╯︵ ┻━┻

Ugh… maybe the fix isn’t as easy as I thought. I must have had some left over data there. I’m pretty sure that data is old so I’ll just refresh the database.

$ php artisan migrate:fresh --seed
Dropped all tables successfully.
Migration table created successfully.
Migrating: 1996_02_27_123456_create_pokemon_table
Migrated: 1996_02_27_123456_create_pokemon_table
Seeding: PokemonSeeder

Finally things are going my way. ┬─┬ノ( º _ ºノ)

However, I should make a mental note to run the seeds individually on prod since we can’t just refresh the data there. I wont forget… hopefully.

Now to make sure the tests are passing.

$ phpunit 
PHPUnit 7.1.5 by Sebastian Bergmann and contributors.
..................F. 20 / 20 (100%)Time: 1.33 minutes, Memory: 40.00MBThere was 1 failure:1) Tests\Feature\PokemonTest::test_it_can_retrieve_a_pokemon_by_id
Invalid JSON was returned from the route.

┻━┻ ︵ヽ(`Д´)ノ︵ ┻━┻

In the aftermath historians identified that the tests failed due to missing $this->seed('PokemonSeeder').

The solution: Seed your initial data in your migrations.

With this, all the above troubles are alleviated and all you have to do is remember to run artisan migrate. This simple and elegant solution has several benefits:

  • Guarantees data is seeded during artisan migrate (without --seed)
  • Prevents accidental re-seeding on subsequent migrations
  • Eliminates the need for $this->seed() in your test cases
  • Avoids the annoying Class does not exist errors

Chris Kankiewicz

Passionate PHP developer, Linux junkie, gamer and hacker.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store