class ActionHandler::Installer

Attributes

args_maker[R]
res_evaluator[R]

Public Class Methods

new( args_maker: ActionHandler::ArgsMaker.new, res_evaluator: ActionHandler::ResponseEvaluator.new ) click to toggle source
# File lib/action_handler/installer.rb, line 16
def initialize(
  args_maker: ActionHandler::ArgsMaker.new,
  res_evaluator: ActionHandler::ResponseEvaluator.new
)
  @args_maker = args_maker
  @res_evaluator = res_evaluator
end

Public Instance Methods

install(ctrl_class, &block) click to toggle source
Calls superclass method
# File lib/action_handler/installer.rb, line 24
def install(ctrl_class, &block)
  ctrl_class.instance_variable_set(:@_action_handler_factory, block)

  installer = self
  initializer = Module.new.tap do |m|
    m.send(:define_method, :initialize) do |*args|
      factory = self.class.instance_variable_get(:@_action_handler_factory)
      handler = factory.call
      config = ActionHandler::Config.get(handler.class)
      self.class.class_eval(&config.as_controller) if config&.as_controller
      installer.send(:setup, self, handler)

      super(*args)
    end
  end

  ctrl_class.prepend initializer
end

Private Instance Methods

action_methods(handler, config) click to toggle source
# File lib/action_handler/installer.rb, line 64
        def action_methods(handler, config)
  config.action_methods || own_public_methods(handler)
end
args_supplier(config) click to toggle source
# File lib/action_handler/installer.rb, line 68
        def args_supplier(config)
  args_hash = {}

  config.args_suppliers.each do |supplier|
    own_public_methods(supplier).each do |name|
      args_hash[name] = supplier.method(name)
    end
  end

  args_hash = args_hash.merge(config.custom_args)
  ActionHandler::Args.from_hash(args_hash)
end
own_public_methods(obj) click to toggle source

List all public methods except super class methods.

# File lib/action_handler/installer.rb, line 82
        def own_public_methods(obj)
  methods = obj.public_methods
  obj.class.ancestors.drop(1).inject(methods) do |ms, sp|
    ms - sp.instance_methods
  end
end
setup(ctrl, handler) click to toggle source
# File lib/action_handler/installer.rb, line 43
        def setup(ctrl, handler)
  config = ActionHandler::Config.get(handler.class) || ActionHandler::Config.new

  actions = action_methods(handler, config)
  args_supplier = args_supplier(config)

  actions.each do |name|
    installer = self

    # If we use `define_singleton_method`, methods don't work correctly.
    # I don't know Rails internal details but
    # Rails requires methods to be defined in a class.
    ctrl.class.send(:define_method, name) do
      method = handler.method(name)
      args = installer.args_maker.make_args(method, args_supplier, context: self)
      res = method.call(*args)
      installer.res_evaluator.evaluate(self, res)
    end
  end
end