Using proprietary database features in Rails via progressive enhancement

In theory, I’ve always liked the database agnosticism of Rails migrations. But, in practice, my migrations are PostgreSQL-specific because I usually fall back to writing SQL DDL statements since standard migrations can’t create essential database features like foreign key constraints and uniqueness constraints (which must exist in the db layer as well as the model layer or you’ll eventually have problems).

I thought of a solution that probably seems obvious to many developers, but I didn’t realize it till now.

From now on, I’ll write as much as I can using standard Rails migrations and then tack on Postgres-specific enhancements wrapped in a test that returns true if-and-only-if the database is Postgres. ActiveRecord makes it easy to test for the database adapter:

if ActiveRecord::Base.connection.adapter_name == ‘MySQL’

This embraces the same progressive enhancement principle advocated for adding JavaScript to web pages, for example.

This way, Rails migrations remain database agnostic yet also can add use proprietary database extensions. An added bonus: future developers can see the conditional code and adapt it for other databases if they wish.

Posted by James on Tuesday, October 04, 2011