What's New in Edge Rails: Database Seeding

Posted by ryan
at 8:44 AM on Wednesday, May 13, 2009

This feature is schedule for: Rails v3.0

I’m not sure if this was ever stated explicitly has a preferred practice or not, but for the longest time many of us have recognized that using migrations as a way to populate the database with a base configuration dataset is wrong. Migrations are for manipulating the structure of your database, not for the data within it and certainly not for simple population tasks.

Well, this practice now has a formal support in Rails with the addition of the database seeding feature. Quite simply this is a rake task that sucks in the data specified in a db/seeds.rb. Here are the details:

Specify Seed Data

Add or open the db/seeds.rb file and put in model creation statements (or any ruby code) for the data you need to be present in order for your application to run. I.e. configuration and default data (and nothing more):

1
2
[:admin, :user].each { |r| Role.create(:name => r) }
User.create(:login => 'admin', :role => Role.find_by_name('admin'))

Load the Data

Once that is in place you can run one of two rake tasks that will populate the database with this data: rake db:seed which will only populate the db with this data and rake db:setup which will create the db, load the schema and then load the seed data. This is the task you’ll want to use if you’re starting in a fresh environment.

So, quit overloading your migrations with seed data and use this new facility. But, don’t go overboard and use seeds.rb for test or staging datasets – it should only be used for the base data that is necessary for your app to run.

tags: ruby, rubyonrails

Comments

Leave a response

  1. Peter WagenetMay 13, 2009 @ 09:20 AM

    Looks good. It’s about time there was an approved solution for this issue.

  2. Maksim HorbulMay 13, 2009 @ 10:32 AM

    That’s exactly what I have faced about one week ago. I put a ton of model creation/modification code into the migrations. Thanks !

  3. Ben HughesMay 13, 2009 @ 11:12 AM

    The problem that is still yet to be solved is how to deal with changing seed data, which is exactly why so many people have and continue to use migrations. What happens if as you go on developing you now add a new role or base user and have to expand your example? You can’t just add this and re-run the file since you’d be getting duplicate records. In other words, this simply doesn’t scale with change management like database migrations do. I’m not sure what the solution is but the above implementation of seed data just isn’t going to work for many of us.

  4. Jason CampbellMay 13, 2009 @ 11:36 AM

    This is a great addition! Something I have been manually adding for a long time.

    One thing which may need some consideration is the addition of support for different environments. My current seed task for production loads a very different set of data than my development seed task.

  5. dobMay 13, 2009 @ 12:03 PM

    If this new feature isn’t to be used for staging/production seeds, is there a suggested facility for doing so?

  6. Arnaud BerthomierMay 13, 2009 @ 12:04 PM

    I have been using this for a while as it solved the seeding problem in Rails 2.x very well.

    http://github.com/mbleigh/seed-fu/tree/master

    My 2 cents. :)

  7. mrkrisMay 13, 2009 @ 05:58 PM

    They’re hijacking my seed_fu `rake db:seed’ task for this hacky implementation? How well will seeds.rb scale when you have a monstrous application? I don’t think this was thought through.

  8. Ryan DaigleMay 14, 2009 @ 07:12 AM

    dob: I usually write my own rake task, something like rake data:load:staging, to load a particular test/staging dataset.

  9. Sergio PereiraMay 14, 2009 @ 08:39 AM

    It might be early to say until I get to try this thing in a real project, but it doesn’t sound all that great. As others already said, seed_fu seems to deliver a nicer solution. I hope I’m missing something.

  10. Shaun McDonaldMay 14, 2009 @ 07:24 PM

    So how does this work when you have a migration, say 20 (yes we still use the old numbering system), needs to load a set of data?