Data Seeding in Ruby on Rails 2.3.4

I just started building a new Rails application in version 2.3.4. One feature that I thought was particularly handy is the data seeding that is now built into Ruby on Rails.

Before this feature, you would have to do one of two things. You could seed your data in your migrations. The problem with this approach is that it clutters up your migrations, and can make for more brittle migrations. It also may or may not propagate to your test database when you run your tests, meaning that if you’re counting on it, it may not bee there.

Your second option was to create fixtures and a rake task to import the fixture data into your Rails application. The problem with this is the need to create multiple related objects across multiple files to make all of your data match up, which can create maintenance problems.

So, without further ado, here is the solution now included in Rails. You simple create a file at db/seeds.rb and place ActiveRecord create calls in the file. Here’s an example seeds.rb.

Role.create(:name => "admin")
User.create(:name => "Chuck Wood", :username => "chuck", :password => "chuck")

Post.create(:title => "Welcome to the blog",
                  :content => "Welcome to my blog! I hope you enjoy it!",
                  :author => User.find_by_name("Chuck Wood"))

Once you have this file, all you need to do is run rake db:setup to create the database and seed the data or rake db:seed to seed the data into an existing database.

{ 7 comments… read them below or add one }

mrkris September 23, 2009 at 8:44 am

I was rather let down with the implementation of the seeding. If you run the seeding multiple times, it will create the data multiple times, unless you write the code to do otherwise. I don’t like this approach personally. I recommend you check out seed_fu, it’s what I’ve been using for quite a while and will continue to use until Rails implements a larger featureset.

Reply

Kevin September 23, 2009 at 11:28 am

I originally started backporting Rails 3 seeds before 2.3.4 was released.

http://github.com/n3bulous/seed4rails2/

The main benefits are handling all your seed data as YAML and being able to order them by just using a default seed.rb file, like:

http://github.com/n3bulous/seed4rails2/blob/master/seed4r2.rb

Still needs some improvements, but I’ve been short on time and its low on the priority list. #1 pending change is a rake task to generate a timestamped yaml file. #2 task is migrating my local day-job changes to the github version.

Reply

Bill September 23, 2009 at 3:54 pm

@mrkris: It takes 1 line to wipe out any models you do not want in seed.rb. Can you point to advantages of seed_fu?

Reply

Chuck September 23, 2009 at 5:14 pm

I’ll probably have a look at seed_fu, but if you’re worried about duplicate entries by running the rake tasks multiple times, you could use the Model.find_or_create_by_… methods. Are there other features to seed_fu?

Reply

Jamie October 22, 2009 at 4:06 pm

I’d just like to mention that the file needs to be db/seeds.rb rather than db/seed.rb as you said…spent hours trying to figure out why it wouldn’t work.

Reply

Chuck October 23, 2009 at 9:56 am

I fixed it. Thanks for pointing that out.

Reply

Kip March 6, 2010 at 4:08 pm

I’m using this method, but it’s not working when running tests. The “rake test” command wipes the database prior to running them. I even tried putting “require RAILS_ROOT + ‘/db/seeds'” in the test_helper.rb file, but that didn’t work. How can I get the seed data to be loaded prior to the tests?

Reply

Leave a Comment

{ 1 trackback }