Tuesday, July 24, 2007

TextHelper revisit

the little things...

The Inflector module in Rails' Active Support library is responsible for the pluralize (as well as singularize, titleize, camelize, etc.) word fun that we all love. But, I often forget about the extra love provided by TextHelper module in ActiveView::Helpers.

I was just about to add a method to my application helper in a recent app that would allow me to pass a count value as well as a string value and get back either a plural or singular form of the word based on the count (using the respective inflector methods). As I started to type out the couple of lines to do this, the light bulb went on. Wait a minute I think Rails already does this for me. Sure enough, fire up the API and there it is in ActionView::Helpers::TextHelpers,
pluralize(count, singular, plural=nil)

In case you haven't looked at the TextHelper module API in a bit, don't forget all the fun stuff that you don't need to re-invent yourself, like: word_wrap, truncate, strip_tags, strip_links, sanitize, highlight, excerpt, etc.

Monday, July 2, 2007

eager loading nested associations

I had a need to eager load some nested associations in a Rails application. The syntax seemed a little tricky at first but made sense once I started working with it.

As an example of the type of model hierarchy, assume a few levels of has_many/belongs_to defined. Also, I'm working with the models via nested restful routes. Here is a similar example to give an idea of the type of data hierarchy.

map.resources :cars do |cars|
cars.resources :makes do |makes|
makes.resources :models do |models|
models.resources :styles

The syntax to eager load the cars model including its nested associations is:
@car = Car.find(:first,
:include => {:makes => {:models => :styles}})

So, the idea is to pass the desired eager loading request as nested hashes, with the key for each being the next successive model to eager load and its value is a hash of yet the next successive model. The syntax feels a bit different then if we were only eager loading one level down in which case we would pass an array of models to the :include. But, once you think about it, it makes perfect sense that you would need to pass a hash of values to eager load additional children. I guess it was just the nested hashes that caught me a little off guard at first.