class Granite::Action::Projectors::ProjectorsCollection

Public Class Methods

new(action_class) click to toggle source
# File lib/granite/action/projectors.rb, line 7
def initialize(action_class)
  @action_class = action_class
  @storage = {}
  @cache = {}
end

Public Instance Methods

fetch(name) click to toggle source
# File lib/granite/action/projectors.rb, line 13
def fetch(name)
  @cache[name.to_sym] ||= setup_projector(name)
end
names() click to toggle source
# File lib/granite/action/projectors.rb, line 25
def names
  @storage.keys | (@action_class.superclass < Granite::Action ? @action_class.superclass._projectors.names : [])
end
store(name, options, &block) click to toggle source
# File lib/granite/action/projectors.rb, line 17
def store(name, options, &block)
  old_options, old_blocks = fetch_options_and_blocks(name)
  @storage[name.to_sym] = [
    old_options.merge(options || {}),
    old_blocks + [block].compact
  ]
end

Private Instance Methods

fetch_options_and_blocks(name) click to toggle source
# File lib/granite/action/projectors.rb, line 58
def fetch_options_and_blocks(name)
  name = name.to_sym
  options, blocks = @storage[name.to_sym]
  options ||= {}
  blocks ||= []

  [options, blocks]
end
projector_superclass(name, projector_name, options) click to toggle source
# File lib/granite/action/projectors.rb, line 67
def projector_superclass(name, projector_name, options)
  superclass = options[:class_name].presence.try(:constantize)
  superclass ||= @action_class.superclass._projectors.fetch(name) if @action_class.superclass < Granite::Action

  superclass || projector_name.safe_constantize || Granite::Projector
end
redefine_const(name, klass) click to toggle source
# File lib/granite/action/projectors.rb, line 50
def redefine_const(name, klass)
  if @action_class.const_defined?(name, false)
    @action_class.__send__(:remove_const, name)
    # TODO: this remove is confusing, would be better to raise? - ask @pyromaniac
  end
  @action_class.const_set(name, klass)
end
setup_projector(name) click to toggle source
# File lib/granite/action/projectors.rb, line 31
def setup_projector(name)
  options, blocks = fetch_options_and_blocks(name)

  projector_name = "#{name}_projector".classify
  controller_name = "#{name}_controller".classify

  projector = Class.new(projector_superclass(name, projector_name, options))
  projector.action_class = @action_class

  redefine_const(projector_name, projector)
  redefine_const(controller_name, projector.controller_class)

  blocks.each do |block|
    projector.class_eval(&block)
  end

  projector
end