Seed Data in Rails 19

Friday, November 16

Someone asked me about this the other day, so I thought I’d write about it. In some of my applications, I need to “seed” the database with data. This might be a list of categories, sections, or other defaults.

There are a couple of ways you can do this. One way is to use migrations. You create records in your migration via ActiveRecord as you normally would, and when you run your migrations, the data is inserted. This works OK, except it obscures the location of the data. By the time you have a lot of migrations, you’re unlikely to remember that 003_create_categories.rb is also the place where you’re adding your default categories.

I like to think of migrations as being transient. As your schema grows and your project evolves, the chances of your migrations running perfectly from top to bottom diminish. When bootstrapping a database, it’s a much better idea to load the entire schema via db:schema:load than running through each transformation with migrations.

So, if we’re not using migrations for seed data, where do we keep it? I like to use YAML fixtures for this. You could use the test fixtures from test/fixtures, but this is an inappropriate location. If you were a new developer coming on to a project, why would you think to look in the test directory for seed data? Test fixtures are for your tests.

For seed data, I create a fixtures directory inside the existing db/ directory: db/fixtures. Then I use the following Rake task, called db:seed to load them:

namespace :db do
  desc "Load seed fixtures (from db/fixtures) into the current environment's database." 
  task :seed => :environment do
    require 'active_record/fixtures'
    Dir.glob(RAILS_ROOT + '/db/fixtures/*.yml').each do |file|
      Fixtures.create_fixtures('db/fixtures', File.basename(file, '.*'))
    end
  end
end

So, I might have something like db/fixtures/categories.yml. When I’m bootstrapping the project on a new machine (say, when deploying), I’d just do the following:

$ rake db:create:all
$ rake db:schema:load
$ rake db:seed

How are other folks out there dealing with seed data?

Edit in Textmate on Leopard

Thursday, November 15

After upgrading to Leopard, I noticed that the ‘Edit in TextMate’ command stopped working. This is a neat little hack that allows you to edit the contents of just about any Cocoa text control within TextMate. At first I was like, meh, no big deal. But after living without it for a few weeks, I realized just how useful it is.

A bit of googling revealed the cause: the rules governing Input Managers have changed in Leopard. Fortunately, TextMate creator Allan Odgaard has a detailed post on how to fix this.

http://blog.macromates.com/2007/inputmanagers-on-leopard

Related: SIMBL Hacks

Also affected by the change to Input Managers were some of my SIMBL hacks, specifically, the hack that I used to customize the default colours of Terminal.app: Mike Solomon’s TerminalColors. Being designed for Tiger’s Terminal.app, this wasn’t working for the new Leopard version.

Ciaran Walsh has re-hacked the hack, and I’m happy to report that I can finally read blue on a black background again. Thanks Ciaran!

http://ciaranwal.sh/2007/11/01/customising-colours-in-leopard-terminal

BTW, the new Terminal.app is completely awesome. Finally, a fast, tabbed terminal for OS X.