JasonDaly.name

PHP, Ruby, Symfony, Rails, Doctrine, MooTools. Web Development.

Posts tagged with "gem"

October 12, 2011

Decorating Models from the View Layer with Draper

Draper is a great gem allowing for the Decorator pattern to easily be applied to ActiveRecord models.

When integrating Draper into an existing application, a decorator or collection of decorators must be retrieved/built instead of ActiveRecord models in order to use the functionality of your decorators (the decorators include all functionality of the ActiveRecord model they’re decorating). Draper’s README explains three methods for doing this from within the controller:

  • Call .new and pass in the object to be wrapped

    ArticleDecorator.new(Article.find(params[:id]))
    
  • Call .decorate and pass in an object or collection of objects to be wrapped:

    ArticleDecorator.decorate(Article.first) # Returns one instance of ArticleDecorator
    ArticleDecorator.decorate(Article.all)   # Returns an array of ArticleDecorator instances
    
  • Call .find to do automatically do a lookup on the decorates class:

    ArticleDecorator.find(1)
    

I’d like to decorate ActiveRecord models from the view directly, leaving the controllers unchanged (directly fetching the record(s) through ActiveRecord). I use the following decorate method in app/helpers/application_helper.rb.

def decorate(records)
  collection = [records] if !objects.is_a? Array
  return records unless collection.first.class.name.match(/Decorator$/).nil?
  klass = (collection.first.class.name + 'Decorator').constantize

  decorated_objects = []
  collection.each do |object|
    decorated_records.push(klass.decorate(object))
  end

  return decorated_records if records.is_a? Array
  decorated_records.first
end

Now I can simply wrap any record or collection with decorate in any view to leverage the decorator functionality.

15 notes Tags: ruby draper gem code rails ruby on rails tips decorator helpers