Created
October 9, 2013 19:07
-
-
Save saturnflyer/6906478 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'delegate' | |
# Public: This class initializes a presenter object. | |
# The presenter wraps a given object and a view object and will forward | |
# method calls to each. By default, any unknown method will be passed | |
# to the first object. | |
# Any methods that need to be sent to the view, may be done explicitly. | |
# | |
# Examples: | |
# | |
# # Inside a controller you create a helper method to access this object | |
# | |
# def presenter | |
# @presenter ||= ProfilePresenter.new(@profile, view_context) | |
# end | |
# helper_method :presenter | |
# | |
# # Inside the view, the "presenter" helper method may be accessed | |
# | |
# <% presenter.with_military_branch do %> | |
# <p><strong>Military Branch:</strong> <%= presenter.branch %></p> | |
# <% end %> | |
# | |
class Presenter < SimpleDelegator | |
# Private: Creates aliased method names for __getobj__ and __setobj__ | |
# which better reflect the wrapped object. | |
# | |
# Examples: | |
# | |
# class ThingPresenter < Presenter; end | |
# presenter = ThingPresenter.new(thing, view) | |
# | |
# presenter.respond_to?(:thing) #=> true | |
# presenter.respond_to?(:thing=) #=> true | |
# | |
def self.inherited(base) | |
wrapped_object_name = base.name.split('::').last.sub('Presenter','').underscore | |
base.send(:alias_method, wrapped_object_name, :__getobj__) | |
base.send(:alias_method, "#{wrapped_object_name}=", :__setobj__) | |
end | |
# Private: This overrides the initialize method in SimpleDelegator and | |
# calls super to wrap the given object. Then it sets the second argument | |
# as the view. | |
def initialize(object, view) | |
super(object) | |
@view = view | |
end | |
private | |
attr_reader :view | |
# Private: Enumerate a collection with the given block | |
# wrapping each object with an instance of the given class | |
# | |
# Examples: | |
# | |
def wrapped_enum(wrapper_class, enumerable, &block) | |
wrapper = wrapper_class.new(nil, view) | |
enumerable.each do |slot| | |
wrapper.__setobj__(slot) | |
block.call(wrapper) | |
end | |
end | |
delegate :current_page, :paginate, :link_to, to: :view | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment