Populating a database in a Laravel migration file
I know this is an old post but since it comes up in a google search I thought I'd share some knowledge here. @erin-geyer pointed out that mixing migrations and seeders can create headaches and @justamartin countered that sometimes you want/need data to be populated as part of your deployment.
I'd go one step further and say that sometimes it is desirable to be able to roll out data changes consistently so that you can for example deploy to staging, see that all is well, and then deploy to production with confidence of the same results (and not have to remember to run some manual step).
However, there is still value in separating out the seed and the migration as those are two related but distinct concerns. Our team has compromised by creating migrations which call seeders. This looks like:
public function up()
{
Artisan::call( 'db:seed', [
'--class' => 'SomeSeeder',
'--force' => true ]
);
}
This allows you to execute a seed one time just like a migration. You can also implement logic that prevents or augments behavior. For example:
public function up()
{
if ( SomeModel::count() < 10 )
{
Artisan::call( 'db:seed', [
'--class' => 'SomeSeeder',
'--force' => true ]
);
}
}
This would obviously conditionally execute your seeder if there are less than 10 SomeModels. This is useful if you want to include the seeder as a standard seeder that executed when you call artisan db:seed
as well as when you migrate so that you don't "double up". You may also create a reverse seeder so that rollbacks works as expected, e.g.
public function down()
{
Artisan::call( 'db:seed', [
'--class' => 'ReverseSomeSeeder',
'--force' => true ]
);
}
The second parameter --force
is required to enable to seeder to run in a production environment.
Don't put the DB::insert() inside of the Schema::create(), because the create method has to finish making the table before you can insert stuff. Try this instead:
public function up()
{
// Create the table
Schema::create('users', function($table){
$table->increments('id');
$table->string('email', 255);
$table->string('password', 64);
$table->boolean('verified');
$table->string('token', 255);
$table->timestamps();
});
// Insert some stuff
DB::table('users')->insert(
array(
'email' => '[email protected]',
'verified' => true
)
);
}