Seed Fu: Simple Seed Data for Rails

The issue of pre-loading needed data for a Rails application has always been somewhat confusing and difficult. A great post on Rail Spikes discusses the issue in-depth and offers a number of different solutions, but ultimately they all seem just a little short of the desired simplicity. By combining a few of the ideas and adding a few of my own, I have created a seeding system that I feel is very straightforward and easy to use.

Borrowing the basic premise of the db-populate plugin, Seed Fu is based around loading ruby scripts located in db/fixtures via a Rake task. What db-populate doesn’t offer is a clear syntax for describing the records to be seeded. That’s where Seed Fu comes in.

Usage

First, just create a new ruby script in db/fixtures (and create the directory itself, obviously). Any script that you drop in this folder will be automatically run when you execute your seeding rake task. Additionally, you can load environment-specific data by adding scripts in a folder of the same name (i.e. db/fixtures/development. In these scripts you can execute arbitrary Ruby code with the full Rails environment loaded; however, you should remember that this code will be executed every time the rake task is called and should not cause duplication or destroy anything that can’t be retrieved. The syntax for Seed Fu works as follows (with a User model as an example):

# db/fixtures/users.rb
# put as many seeds as you like in

User.seed(:login, :email) do |s|
  s.login = "admin" 
  s.email = "admin@adminnerson.com" 
  s.first_name = "Bob" 
  s.last_name = "Bobson" 
end

User.seed(:login, :email) do |s|
  s.login = "michael" 
  s.email = "michael@abc.com" 
  s.first_name = "Michael" 
  s.last_name = "Bleigh" 
end

The seed method is available on any ActiveRecord. It takes as parameters the ‘constraints’ for that seeding; in other words, the fixed attributes that will not change in the record’s life. The constraints are used to find the record and update instead of creating it with the attributes provided if it already exists. This way your seeds can change without mucking with other live data on your server.

Once you have set up your fixtures, it’s simple to run them:

rake db:seed

Or if you want to run them for a targeted environment:

rake db:seed RAILS_ENV=production

Installation

In edge Rails or Rails 2.1 and beyond:

script/plugin install git://github.com/mbleigh/seed-fu.git

In previous versions of Rails:

git clone git://github.com/mbleigh/seed-fu.git vendor/plugins/seed-fu

I have some ideas for the expansion of this plugin (loading from CSV for larger datasets, etc.), so stay tuned! If you have ideas for additional features or encounter any problems, I have set up a Lighthouse project for your enjoyment.

Share:

18 Responses to “Seed Fu: Simple Seed Data for Rails”

  1. Mark

    Off topic, but this site is built with I am assuming RoR. So my question is, what do you use for formatting your code? A gem, a plugin, homemade concoction, simple CSS?
  2. gregf

    Great! Just what i been wanting. :)
  3. j4s0n

    hope it extends to random generating a series of data for common attributes like firstname,middlename,email,address and etc... etc... I'm too demanding, but here's what's in my mind. s.first_name = ["john","anothername","anothername","anothername"] s.last_name = ["smith","anothername","anothername","anothername"] Cheers and Thanks =)
  4. j4s0n

    Oh dear, the formatting looks awful. But i believe you get what I mean hehe.
  5. Hendrik Mans

    Thanks to "record.attributes = @data", seed_fu becomes pretty much useless in most situations where you have models with protected attributes. Simple to fix, though: http://pastie.textmate.org/184297
  6. Cristi Balan

    A nice addition to this wold be to have a toggle for the forced updating of the model. Or at least have it overwrite on development and just create if not existent on production. This would help if you wanted to add new default data to a running production app, for example. Will send a patch for this if I get some time to work on it.
  7. j4s0n

    Err... Where did my comment go? Sigh =(
  8. Luke Francl

    Looks cool, I will have to check this out. (And thanks for the link!) j4s0n -- what you really want is fuzzing. There's some libraries like Faker and Forgery that do what you want. I wrote a post on that, too: http://railspikes.com/2008/1/25/fuzzing-your-database
  9. Derrick

    Nice plugin! Just what I needed.
  10. Darcy

    Love this plugin. Like Cristi though - I needed a way to not always update once it was on production, etc. Quick hack to do that: http://pastie.textmate.org/218362
  11. Marcus

    Darcy's changes are pretty cool. Maybe those could be incorporated? They don't require any changes to existing seeds.
  12. David Spurr

    I have an observer registered which sends out emails when a user is created/updated. This seems to be causing problems when using seed-fu as I get the following error: Unprocessed view path found: nil. Set your view paths with #append_view_path, #prepend_view_path, or #view_paths=. I've tried setting the view_paths on ActionController::Base at the beginning of the seed fixture that is causing me problems but that doesn't seem to help. Any ideas?
  13. Bill Burcham

    +1 for seed-fu. You guys rock!
  14. Bill Burcham

    There is a problem with the plugin install for those of us who are using Git to manage our own projects. The plugin install leaves the .git directory (hierarchy) in place in /vendor/plugins/seed-fu This causes subsequent commits (of my own project) to ignore /vendor/plugins/seed-fu The result is that team mates doing a git pull do not see seed-fu. Instead they just see an empty directory. I resolved this in my project by simply removing (rm -fr) /vendor/plugins/seed-fu/.git This is similar to the way the rspec-rails folks handle their plug-in: http://github.com/dchelimsky/rspec-rails/wikis It'd be nice though if it was not a manual step.
  15. Karim Helal

    Excellent plugin! One problem that I am having tho is when trying to seed a database table that is a tree structure. When I try to manually set the parent_id, lft and rgt, I get an error that says: "Unauthorized assignment to parent_id: it's an internal field handled by acts_as_nested_set code, use move_to_* methods instead." How to fix this? I've tried to use the move_to commands, but then seed complains that he can't understand the commands...
  16. rubian

    nice plugin! But how to update the active record relations by this plugin?
  17. Bill Burcham

    Here's a patch that makes 1-1 associations work in the constraints: http://gist.github.com/21188
  18. sub

    I found this plugin quite useful. just a question, is there any kind of possibility to update m-n relations?


Leave a Reply