class StrongPresenter::PresenterHelperConstructor

@private Defines helper methods in controllers to access instance variables as presenters

Attributes

block[RW]
controller_class[RW]
factory[RW]
presenter[RW]

Public Class Methods

new(controller_class, block, options) click to toggle source

settings: controller to define in, presenter factory, block to execute, options for valid actions

# File lib/strong_presenter/presenter_helper_constructor.rb, line 6
def initialize(controller_class, block, options)
  @controller_class = controller_class
  @factory = StrongPresenter::Factory.new(options.slice!(:only, :except))
  @block = block
  @action_matcher = setup_action_matcher(options)
end

Public Instance Methods

call(variable) click to toggle source

call to construct helper

# File lib/strong_presenter/presenter_helper_constructor.rb, line 20
def call(variable)
  @object = "@#{variable}"
  @presenter = "@#{variable}_presenter"
  construct(variable)
end
setup_action_matcher(options) click to toggle source

Returns proc to check if action matches

# File lib/strong_presenter/presenter_helper_constructor.rb, line 14
def setup_action_matcher(options)
  options.each { |k,v| options[k] = Array(v).map(&:to_sym) unless v.nil? }
  ->(action) { (options[:only].nil? || options[:only].include?(action)) && (options[:except].nil? || !options[:except].include?(action)) }
end

Private Instance Methods

construct(variable) click to toggle source

actually construct the helper

# File lib/strong_presenter/presenter_helper_constructor.rb, line 30
def construct(variable)
  shadowed_method = get_shadow_method(variable)
  action_matcher = @action_matcher
  memoized_presenter = method(:memoized_presenter).to_proc

  controller_class.send :define_method, variable do |*args|
    return shadowed_method.call self, *args unless action_matcher.call(action_name.to_sym) # scoped by controller action?
    raise ArgumentError.new("wrong number of arguments (#{args.size} for 0)") unless args.empty?
    memoized_presenter.call(self)
  end
end
get_shadow_method(method_name) click to toggle source

method which will be shadowed by the defined helper

# File lib/strong_presenter/presenter_helper_constructor.rb, line 43
def get_shadow_method(method_name) # alias_method_chain without name pollution
  shadowed_method = controller_class.send :instance_method, method_name if controller_class.send :method_defined?, method_name
  return lambda { |obj, *args| raise NoMethodError } if shadowed_method.nil?
  return lambda { |obj, *args| shadowed_method.bind(obj).call(*args) }
end
memoized_presenter(controller) click to toggle source

get presenter, memoized

# File lib/strong_presenter/presenter_helper_constructor.rb, line 50
def memoized_presenter(controller)
  return controller.send(:instance_variable_get, presenter) if controller.send(:instance_variable_defined?, presenter)
  controller.send(:instance_variable_set, presenter, wrapped_object(controller))
end
wrapped_object(controller) click to toggle source

wrap model with presenter and return

# File lib/strong_presenter/presenter_helper_constructor.rb, line 56
def wrapped_object(controller)
  factory.wrap(controller.send :instance_variable_get, @object) { |presenter| self.instance_exec presenter, &block unless block.nil? }
end