Mood Swing
As we’ve been taught, conditional statements can be a code smell and a good way to clean them up is polymorphism. I’ve found that with rails coupling the persistence layer and the business logic sometimes the standard form of inheritance- based polymorphism is awkward or not feasible. However, Ruby with it’s dynamic object model can provide a form of inheritance via extending instances by mixing in modules dynamically. Mood Swing embraces this and provides a convenient means of doing it.
Usage
You simply define the class macro mood_trigger and pass it the attribute in which will be used to load the module. The value of the attribute will be inflected with .classify and then a module matching “#valueExtension” will be loaded if it is available with in the class namespace. Given the mood_trigger attribute is breed, with a value of hound, in the class named Dog, then the module would be named Dog::HoundExtension.
class Dog < ActiveRecord::Base
mood_trigger 'breed'
def
'woof'
end
module HoundExtension
def
'Hoooooowl'
end
end
end
Now whenever you load a dog with the breed set to hound, or if you assign the breed to hound, it will bark out “Hoooooowl”
Optionally, you can supply a writer attribute if the writer is not the same as the reader. This is the case with with polymorphic associations.
belongs_to 'body', :polymorphic => true
mood_trigger 'body_type', :writer => 'body'