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.
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 = "email@example.com" s.first_name = "Bob" s.last_name = "Bobson" end User.seed(:login, :email) do |s| s.login = "michael" s.email = "firstname.lastname@example.org" s.first_name = "Michael" s.last_name = "Bleigh" end
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:
Or if you want to run them for a targeted environment:
rake db:seed RAILS_ENV=production
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.