Snapi

Section 6

Decorator

Decorator

Responsibility

  • Object-oriented layer of presentation logic

Decorators are the ideal place to:

  • format complex data for user display
  • define commonly-used representations of an object, like a name method that combines first_name and last_name attributes
  • mark up attributes with a little semantic HTML, like turning a url field into a hyperlink

include magic

class ContactCurator < BaseCurator
  include Omicron.decoration(ContactDecorator)

  def show_action
    pipe(default_response, :through => [
      :find, :authorize_to_read, :apply_readables, 
      :set_is_editable, :decorate
    ])
  end
end

We use the include magic to
inject decorate into the app. 

class Response
  include Virtus.value_object

  values do
    attribute :status, Integer, :default => 200
    attribute :headers, Hash, :default => {}
    attribute :collection, Array, :default => []
    attribute :original_collection, Array, :default => []
    attribute :page_information, Hash
    attribute :error_message, String
  end
end

Concepts

  • Draper::Decorator

  • delegate_all

  • DateTimeDecorator.decorate

class ContactDecorator < Draper::Decorator
  delegate_all

  include DateTimeDecorator.decorate(:created_at, :updated_at)

  def first_name
    user_id.nil? ? object.first_name : object.user_first_name
  end

  def last_name
    user_id.nil? ? object.last_name : object.user_last_name
  end

  def address_street1
    is_address_hidden? ? "" : object.address_street1
  end
  private

  def is_address_hidden?
    object.is_address_hidden && !object.is_address_readable?
  end

  def is_invitation_hidden?
    !object.is_invitation_readable?
  end
end

https://github.com/drapergem/draper

Draper::Decorator

Ruby Gem called Draper.

Draper adds an object-oriented layer of presentation logic
to your Rails application.

 

delegate_all

Delegates all functions to the internal item.

You can reference the item by accessing object.

class ContactDecorator < Draper::Decorator
  delegate_all

  def is_invitation_hidden?
    !object.is_invitation_readable?
  end
end
class ContactDecorator < Draper::Decorator
  delegate_all

  include DateTimeDecorator.decorate(:created_at, :updated_at)

  def first_name
    user_id.nil? ? object.first_name : object.user_first_name
  end

  def last_name
    user_id.nil? ? object.last_name : object.user_last_name
  end

  def address_street1
    is_address_hidden? ? "" : object.address_street1
  end
  private

  def is_address_hidden?
    object.is_address_hidden && !object.is_address_readable?
  end

  def is_invitation_hidden?
    !object.is_invitation_readable?
  end
end

DateTimeDecorator

Formats dates.

class ContactDecorator < Draper::Decorator
  delegate_all

  include DateTimeDecorator.decorate(:created_at, :updated_at)
end


case value
when DateTime
  value.to_time.utc.iso8601.sub(/\+00:00$/, "Z")
when Time
  value.to_time.utc.iso8601.sub(/\+00:00$/, "Z")
when Date
  value.strftime("%Y-%m-%d")
else
  value
end
class ContactDecorator < Draper::Decorator
  delegate_all

  include DateTimeDecorator.decorate(:created_at, :updated_at)

  def first_name
    user_id.nil? ? object.first_name : object.user_first_name
  end

  def last_name
    user_id.nil? ? object.last_name : object.user_last_name
  end

  def address_street1
    is_address_hidden? ? "" : object.address_street1
  end
  private

  def is_address_hidden?
    object.is_address_hidden && !object.is_address_readable?
  end

  def is_invitation_hidden?
    !object.is_invitation_readable?
  end
end

Decorator

Responsibility

  • Object-oriented layer of presentation logic

Thank you!

Made with Slides.com