Sentenced to making sense

Main menu

Monthly Archives: November 2007

The Rails generator script/generate knows pretty well what things it can generate. In fact, it knows much better than I do. So, I think it could really give me some help when I’m typing along on the command line.

If you save the snippet below as /etc/bash_completion.d/generate you can enjoy this help, too.

I’m not yet so enlightened that all of my Rails unit and functional tests run without accessing the database. Indeed, I’m still using YAML fixtures to populate the database for testing.

I also insist on having foreign key constraints in the database, a thing that’s not exactly encouraged by Rails, but which is quite possible nonetheless. The various plugins from RedHill Consulting are a big help.

But then, when you feel all warm and cosy due to the additional safety at the database-level, you’re suddenly trapped by a snag: Sooner or later you find that your fixtures contain dependencies among objects that preclude any attempt at clever ordering by violating one foreign key constraint or another. Fixture files are loaded one after another in their entirety and when an object in an earlier fixture refers to an object in a later fixture, the database aptly notices as an inconsistency.

Well, you may think, it is an inconsistency, but only a temporal one. After all the fixture files are loaded, everything is consistent again. That’s the clue. We need to tell the database that, yes, indeed, things may be inconsistent for a time, but we’ll be cleaning up, promise. The good thing is that there is even an SQL standard-compliant way to express this promise.

START TRANSACTION
SET CONSTRAINTS ALL DEFERRED
COMMIT

If you use transactional fixtures, the transaction bracket is already provided by Rails, but there’s no pretty way to sneak in the "SET CONSTRAINTS ..." line. There are two ways of slightly different brutality. First, you can edit activerecord/lib/fixtures.rb and just insert the required line.

Note that with transactional fixtures this results in each fixture file loaded only once for all the tests.

So, there we are a last. Or those with a reasonable DBMS, I might say. For, of course, this technique is no use, if your database does not support deferrable constraints. PostgreSQL for one does support them.