Permalink
Browse files

Added db/seeds.rb as a default file for storing seed data for the dat…

…abase. Can be loaded with rake db:seed (or created alongside the db with db:setup). (This is also known as the "Stop Putting Gawd Damn Seed Data In Your Migrations" feature) [DHH]
  • Loading branch information...
1 parent 2e7409f commit 4932f7b38f72104819022abca0c952ba6f9888cb @dhh dhh committed May 11, 2009
View
@@ -1,3 +1,8 @@
+*Edge*
+
+* Added db/seeds.rb as a default file for storing seed data for the database. Can be loaded with rake db:seed (or created alongside the db with db:setup). (This is also known as the "Stop Putting Gawd Damn Seed Data In Your Migrations" feature) [DHH]
+
+
*2.3.2 [Final] (March 15, 2009)*
* Remove outdated script/plugin options [Pratik Naik]
View
@@ -200,11 +200,14 @@ task :copy_configs do
cp "configs/locales/en.yml", "#{PKG_DESTINATION}/config/locales/en.yml"
+ cp "configs/seeds.rb", "#{PKG_DESTINATION}/db/seeds.rb"
+
cp "environments/boot.rb", "#{PKG_DESTINATION}/config/boot.rb"
cp "environments/environment.rb", "#{PKG_DESTINATION}/config/environment.rb"
cp "environments/production.rb", "#{PKG_DESTINATION}/config/environments/production.rb"
cp "environments/development.rb", "#{PKG_DESTINATION}/config/environments/development.rb"
cp "environments/test.rb", "#{PKG_DESTINATION}/config/environments/test.rb"
+
end
task :copy_binfiles do
@@ -0,0 +1,7 @@
+# This file should contain all the record creation needed to seed the database with its default values.
+# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
+#
+# Examples:
+#
+# cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }])
+# Major.create(:name => 'Daley', :city => cities.first)
@@ -125,6 +125,7 @@ def create_config_files(m)
create_database_configuration_file(m)
create_routes_file(m)
create_locale_file(m)
+ create_seeds_file(m)
create_initializer_files(m)
create_environment_files(m)
end
@@ -176,6 +177,10 @@ def create_routes_file(m)
m.file "configs/routes.rb", "config/routes.rb"
end
+ def create_seeds_file(m)
+ m.file "configs/seeds.rb", "db/seeds.rb"
+ end
+
def create_initializer_files(m)
%w(
backtrace_silencers
@@ -156,8 +156,8 @@ namespace :db do
Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
end
- desc 'Drops and recreates the database from db/schema.rb for the current environment.'
- task :reset => ['db:drop', 'db:create', 'db:schema:load']
+ desc 'Drops and recreates the database from db/schema.rb for the current environment and loads the seeds.'
+ task :reset => [ 'db:drop', 'db:setup' ]
desc "Retrieves the charset for the current environment's database"
task :charset => :environment do
@@ -206,6 +206,15 @@ namespace :db do
end
end
+ desc 'Create the database, load the schema, and initialize with the seed data'
+ task :setup => [ 'db:create', 'db:schema:load', 'db:seed' ]
+
+ desc 'Load the seed data from db/seeds.rb'
+ task :seed => :environment do
+ seed_file = File.join(Rails.root, 'db', 'seeds.rb')
+ load(seed_file) if File.exist?(seed_file)
+ end
+
namespace :fixtures do
desc "Load fixtures into the current environment's database. Load specific fixtures using FIXTURES=x,y. Load from subdirectory in test/fixtures using FIXTURES_DIR=z. Specify an alternative path (eg. spec/fixtures) using FIXTURES_PATH=spec/fixtures."
task :load => :environment do

44 comments on commit 4932f7b

@pjammer

Now this is an awesome commit. Thanks, as adding seed data was usually one of the first things i'd do in most of my apps.

@akahn
akahn commented on 4932f7b May 11, 2009

What is "seed data"?

@rmoriz
rmoriz commented on 4932f7b May 11, 2009

@akahn initial sql data you'll use in your app. e.g. country data, roles

@arthurschreiber

Great change! :) Until now, I always came up with my own solutions for this, so I'm happy to see this in Rails Core.

@supaspoida

Glad to see this functionality built into rails. Been using seed-fu to keep migrations & data separate for some time now & the technique works really well.

@thiagopradi
Contributor

great work!

@Xac
Xac commented on 4932f7b May 11, 2009

Very nice to see something like this in Rails core. It's about time we standardized the solution to seeding a db.

@ryanb
Contributor
ryanb commented on 4932f7b May 11, 2009

I like the simplicity of this. It only loads a Ruby file and doesn't put any restrictions on how one generates seed data. What this does is create a standard everyone can go with (rake db:seed) and leave the implementation up to the developer. One could load the fixture files, use seed-fu, or even Factory Girl.

@jrmehle
Contributor

It's good to see Rails take a side on the seed data debate. Fixtures, migrations, rake tasks, script/console... There are so many ways you could load seed data. Standardizing on one method should make things easier.

@melvinram

Sweet! I like it.

@apacala

Me approves.

@melvinram

Question: I get that this will run when you run 'rake db:setup', 'rake db:seed' or 'rake db:reset' ... but will it also run when you do 'rake db:migrate' for the first time? And are there other rake tasks other than what I've listed that will cause the seed.rb to be run?

@tilsammans
Contributor

Very nice.

@melvinram

In response to my question earlier: Looking at the code for the migrate task, it doesn't look like it will trigger the seed.rb to be run.

@bcardarella
Contributor

That's pretty cool. No more messy migration files.

@mrichman

I'd love to see this backported to 2.3.x or 2.4!

@pjkelly

If you want something like this in pre-edge rails, check out http://github.com/mbleigh/seed-fu/tree/master.

@andres
andres commented on 4932f7b May 11, 2009

for backporting you can have a little rake tast
desc "Load initial base data"
task :load_base_data => :environment do |t|
require 'db/data_dump.rb' # a file with a class DataDump and a method load that holds your data written in "migration style"
DataDump.load #where initialize loads the data into the database
end

@kivanio
Contributor

great!

@dpickett
Contributor

very nice - good to now have a standard for all that data

@labria
Contributor
labria commented on 4932f7b May 11, 2009

yay

@jstorimer
Contributor

+1 woot

@edward
Contributor
edward commented on 4932f7b May 11, 2009

Awesome. I’ve been looking forward to this puppy for a while.

@grzegorzkazulak

+1 awesome :}

@joefiorini
Contributor

Awesome idea, would love to see a test showing a sample seeds file and how it's expected to be used! :) All around a good feature to have in!

@trevorturk
Contributor

Awesome!

BTW, I think there's a typo in the comments in db/seeds.rb:
Major.create(:name => 'Daley', :city => cities.first)
...should be "Mayor" not "Major" right? :)

@chalkers

How about rolling back or running the seeder twice when some seed data is already there?

@loe
Contributor
loe commented on 4932f7b May 11, 2009

+1 Opinion delivered.

@tvdeyen
Contributor

great

@matharvard

Thanks :)

@samgranieri
Contributor

Thanks DHH!

@aussiegeek
Contributor

Thanks, one of the project I'm working on we've been using fixtures, which never felt like fun

@radar
Contributor
radar commented on 4932f7b May 11, 2009

This is very awesome!

@jinzhu
jinzhu commented on 4932f7b May 12, 2009

awesome commit !
right now I am using config/load_data.rb .

@deepthawtz

would I be stabbed if I didn't agree this was awesome? hypothetical question for ya.

@Knack
Knack commented on 4932f7b May 12, 2009

@chalkers I'm using the plugin 'mbleigh/seed-fu' wich address this issue, because it either creates or updates records, checking the existence of the record based on one or several fields you specify.

In fact, seed_fu already defines a db:seed rake task (maybe a potential conflict).

I like the idea of seeds.rb being just a ruby file, so you can write inside whatever you want: use seed_fu, load one or several yaml files, etc.

@chalkers

@Knack Thanks for the reply. Couldn't "checking the existence of the record based on one or several fields you specify" be expensive?

@blj
blj commented on 4932f7b May 12, 2009

@chalkers, it is expensive only if you want it to be.

@sermoa
sermoa commented on 4932f7b May 12, 2009

NICE! thanks for that! :)

@softprops

+1 for a standardization of a common pattern in migrations.

@fosrias
Contributor

This is cool. Now really cool would be this:

script/generate scaffold MyModule::MyModel --seed
or
script/generate scaffold MyModule::MyModel --seed

creates the file:

..\db\seeds\my_module\my_model.rb

and then the command

rake db:seed Module::model

only runs the model seed file and

rake db:seed

runs all the seed files.

Then you've nailed the functionality.

@fosrias
Contributor

Second generate was meant to be:

script/generate model MyModule::MyModel --seed

and the first rake was meant to be:

rake db:seed MyModule::my_model

GitHub needs to let you edit your comments.

@fosrias
Contributor

Broke down and created a plugin to do it. Manages seeds like models and allows rake db:seed to run individual model seeds, not just a batch.

http://github.com/markwfoster/seeded-generation

@rafaelp

The purpose of Rails task db:seed is for "Seed once" data or "Always seed" data? Do you encourage running db:seed after deploy?

UPDATED:
DHH response on Twitter: "@rafaelp Seed data once. The first time you setup the database. Not every time you deploy. (At least that was the design directive)."
http://twitter.com/dhh/statuses/27425849821110272

Please sign in to comment.