Hashrocket.com / blog

Large decorator

Using SimpleDelegator for your Decorators

posted on and written by Micah Cooper in

Image 100x100 micah cooper

Decorators are great - especially for building Ruby on Rails applications. They help separate the functionality from your models that some would consider "not core". Ruby has a neat class called SimpleDelegator that we've been using to implement the decorator pattern. It's clean, simple, attractive, and good with children which makes it a great candidate for this type of work. So let's use it!

Lets say we have a Person class with #first_name and #last_name attributes and we want to add a #full_name method to this Person.

Create our Person class:


class Person

  attr_reader :first_name, :last_name

  def initialize(first_name, last_name)
    @first_name, @last_name = first_name, last_name
  end

end

Create our PersonDecorator that inherits from SimpleDelegator

And add our #full_name method

class PersonDecorator < SimpleDelegator

  def full_name
    first_name + " " + last_name
  end

end

So there is our decorator. But how would one actually use this? Actual use could look something like this:

Create our person object


person = Person.new('Joe', 'Hashrocket')

person.first_name #=> 'Joe'
person.last_name #=> 'Hashrocket'
person.full_name #=> Method_Missing error

Decorate our person object

decorated_person = PersonDecorator.new(person)

decorated_person.first_name #=> 'Joe'
decorated_person.last_name #=> 'Hashrocket'
decorated_person.full_name #=> 'Joe Hashrocket'

All SimpleDelegator is really doing is giving you method missing. Good stuff...

Now, I want to add a way to handle collections with this decorator. That is something often done with decorators. So, let's add the class method `.wrap to this decorator. Our final version looks like this:

class PersonDecorator < SimpleDelegator

  def self.wrap(collection)
    collection.map do |obj|
        new obj
    end
  end

  def full_name
    first_name + " " + last_name
  end

end

And that's it! Have fun with your new decorator. Of course, there are many other ways to use SimpleDelegator. And there are just as many ways to implement the decorator pattern but I think SimpleDelegator is a pretty clean solution. But, it seems to be lacking in documentation department. Hopefully, this helps you gain a better understanding of SimpleDelegator.

Posted in Development and tagged with Ruby