Bootstrapping your Database with Ordered Fixtures

Ruby on Rails provides a convenient way to ensure consistent database state for all unit tests and this is accomplished through Fixtures.

In the Rails Weenie forums technoweenie presented a technique that allows us to ‘bootstrap’ our development or production database using the same underlying mechanisms.

The way it works is first we place YAML files similar to the ones we use for testing under db/bootstrap (instead of test/fixtures). Then it’s a simple matter of executing:

rake db:bootstrap:load

Fixtures and Referential Integrity

The only problem with the above technique is when your tables have foreign key constraints (as they easily could if you use ActiveRecord Migrations with my own Migrations Constraints Plug-in).

When using fixtures for unit tests, we can explicitly specify the order of the fixtures in code. For example:

fixtures :foo, :bar_references_foo

The original technique by technoweenie allows us to specify a fixture order by an environment variable:

FIXTURES="foo bar_references_foo" rake db:bootstrap:load

While it works, it requires us to specify our fixture names and their order every time – not very DRY if you ask me.

Ordered Fixtures

Sandro Paganotti on also realized this and presented his own version of rake db:bootstrap:load that attempts to address this.

The idea is to let us number our fixtures, similar to how we number our migrations, so that they can be loaded/unloaded in proper order according to our foreign key constraints.

Except, when I looked more closely at his code, I had my reservations.

First, and most glaring, is that he sorts the fixtures array, even if it’s passed in through the FIXTURES environment variable. I think this totally defeats the purpose of explicitly specifying the fixtures that way.

Second, and relatively minor, is that he hard-codes the format of the fixture file names so they have to be 2 digit numbers followed by an underscore, then the table name.

My rake db:bootstrap:load

So I set about to write my own, slightly more evolved version of Sandro Paganotti’s rake task.
Continue reading