Ryan Carmelo Briones

mostly harmless

with_options just got sexier April 11, 2007

I read a lot of technical reference material but sometimes you don't get that "Aha!" moment until you see it in action. Take for instance the with_options method [1] from the Active Support of Rails. Here I am happily coding away at my unit tests when I thought to myself that the following code in my model just didn't look DRY enough.

validates_format_of :phone_number, :with => /\\A(?:[0-9]{3})?[0-9]{7}(?:x[0-9]+)?\\Z/, :message => "Bad phone number message"
validates_format_of :fax_number, :allow_nil => true, :with => /\\A(?:[0-9]{3})?[0-9]{7}(?:x[0-9]+)?\\Z/, :message => "Bad phone number message"

A first I was going to separate out the RegExp and the Message to a constant. Simple enough. But then I thought, "This seems like a job for with_options...but how?" I've seen with_options used on an object, but would it work without one? Google to the rescue! So now I rewrite the above code as:

with_options(:with => /\\A(?:[0-9]{3})?[0-9]{7}(?:x[0-9]+)?\\Z/, :message => "Bad phone number message") do |phone_validation|
phone_validation.validates_format_of :phone_number
phone_validation.validates_format_of :fax_number, :allow_nil => true

That just makes me warm inside.

[1] - Interestingly enough I wanted to link to the Rails API documention for with_options, but, sadly, it is no where to be found. It does have it's own mini-section in "Agile Web Development with Rails, 2ed", though.