DRY out your database.yml
June 27th, 2006
Update: Matt says that Typo uses this scheme for their database.yml, which is likely where I first saw it. Jonathan mentions that this is also included in Rails Recipes, which I have to admit I’ve owned since the day it came out as a betabook but never actually looked at. Thanks, guys!
While paging through NetNewsWire this afternoon, I came across James Duncan Davidson’s article Conditional Rails Database Configuration. “Damn”, thought I, “ERb in the database.yml is a neat trick, but it’s so ugly!”
That reminded me of a little trick I’ve been using for as long as I can remember. I can’t take credit for this technique as I learned it from someone else… I just don’t remember who. Anyway, it goes a little something like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
login: &login adapter: mysql username: username password: password host: mysql.example.com development: <<: *login database: app_dev test: <<: *login database: app_test production: <<: *login database: app_prod |
That’s a pretty standard Rails database.yml, all DRYed out. Like I said, I’ve been doing this forever but I rarely see it in other apps.
To extend on James’ post, here’s what his example would look like if you follow this technique:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
common: &common adapter: mysql dev: &dev <<: *common username: root <% if File.exist? "/opt/local/var/run/mysql5/mysqld.sock" %> socket: /opt/local/var/run/mysql5/mysqld.sock <% elsif File.exist? "/tmp/mysql.sock" %> socket: /tmp/mysql.sock <% end %> development: <<: *dev database: birdy test: <<: *dev database: birdy_test production: <<: *common host: 10.0.1.24 <% if `uname -n`.strip == "staging" %> database: birdy_stage username: birdy_stage password: somethingsecret <% else %> database: birdy username: birdy password: somethingelsethatissecret <% end %> |
Okay okay, it’s ugly for sure. But it’s functional and repetition has been removed where possible, making it less ugly than before. Of course you could get even trickier and tweak with the conditionals in the Production environment, but then you start getting into spaghetti ERb in your database.yml, which has got to be some sort of sin.
So there you go. I’d dearly love to see this method gain more popularity as it’s so much cleaner. I can’t be the only one whose development environment is close enough to his production environment to let this work!
Confidential to James (if you read this): sorry to email you all this crap only to turn around and blog it. Should have blogged it first and emailed you the link! Guess I’m not a Real Blogger yet.
7 Responses to “DRY out your database.yml”
Sorry, comments are closed for this article.
June 27th, 2006 at 05:11 PM
No worries Ben, I’m glad you wrote it up. I like your approach and am going to link to it in my essay. :)
June 27th, 2006 at 05:31 PM
Thanks for the link, James!
June 27th, 2006 at 06:46 PM
Typo uses that in their database.yml
June 27th, 2006 at 11:15 PM
This is also mentioned in the book “Rails Recipes” as “DRY up your database configuration”. It’s indeed underused, so bringing it out in the open is a good thing.
June 28th, 2006 at 08:04 AM
Off Topic: It would be great if you consider registering your blog at RubyCorner.com, a meeting place for people interested in the Ruby Programming Language and related technologies.
July 13th, 2006 at 12:01 AM
Ben,
Thanks for posting this – I’m usually too lazy to remember the syntax tricks to do it. That &/* stuff is standard yaml, eh?
One note on your (fictional) staging set up: maybe it would be better to define the staging environment explicitly. Here’s a good article on the subject: http://glu.ttono.us/articles/2006/05/22/guide-environments-in-rails-1-1
July 13th, 2006 at 08:23 AM
That’s a good tip, Chris! Honestly, I’d never even thought of making my own environment :) That example came straight from James’ post, but my forthcoming Capistrano post includes a similar idea. Thanks!