class DDC::ControllerBuilder

Constants

DEFAULT_CONTEXT_PARAMS
DEFAULT_STATUSES

Public Class Methods

build(controller_name, config) click to toggle source
# File lib/ddc/controller_builder.rb, line 14
def build(controller_name, config)
  klass = find_or_create_class(controller_name, config)
  setup_before_actions!(klass, config)
  setup_actions!(controller_name, klass, config)
  klass
end
find_or_create_class(controller_name, config) click to toggle source
# File lib/ddc/controller_builder.rb, line 43
def find_or_create_class(controller_name, config)
  controller_klass_name = controller_name.to_s.camelize+'Controller'
  klass = nil
  if specific_const_defined?(controller_klass_name)
    klass = specific_const_get(controller_klass_name)
  else
    parent_klass = config[:parent] || ApplicationController
    klass = Class.new(parent_klass)
    specific_const_set(controller_klass_name, klass)
  end
  klass
end
parse_class_and_method(str) click to toggle source
# File lib/ddc/controller_builder.rb, line 135
def parse_class_and_method(str)
  under_klass, method = str.split('#')
  [Object.const_get(under_klass.camelize), method]
end
reduce_contexts(contexts, context_params) click to toggle source
# File lib/ddc/controller_builder.rb, line 71
def reduce_contexts(contexts, context_params)
  computed_contexts = contexts.map do |context_klass, context_method|
    context_klass.new.send(context_method, context_params)
  end
  if computed_contexts.size == 1
    computed_contexts.first
  else
    computed_contexts.reduce({}) do |h, ctx|
      h.merge(ctx)
    end.with_indifferent_access
  end
end
setup_action!(controller_name, klass, action, action_desc, config) click to toggle source
# File lib/ddc/controller_builder.rb, line 84
def setup_action!(controller_name, klass, action, action_desc, config)
  raise "Must specify a service for each action" unless action_desc[:service].present?
  raise "Must specify a context for each action" unless (action_desc[:context].present? || action_desc[:contexts].present?)
  proc_klass, proc_method = parse_class_and_method(action_desc[:service])
  contexts = (action_desc[:contexts] || [action_desc[:context]]).map { |ctx| parse_class_and_method ctx }
  #context_klass, context_method = parse_class_and_method(action_desc[:context])

  klass.send :define_method, action do
    context_params = (action_desc[:context_params] || config[:context_params] || DEFAULT_CONTEXT_PARAMS).inject({}) do |h, param|
      h[param] = send param
      h
    end
    context = DDC::ControllerBuilder.reduce_contexts contexts, context_params

    result = proc_klass.new.send(proc_method, context)
    obj = result[:object]
    errors = result[:errors] || []
    plural_model_name = controller_name.to_s
    model_name = plural_model_name.singularize

    # alias in object as model name
    if obj.is_a? Enumerable
      result[plural_model_name] ||= obj
    else
      result[model_name] ||= obj
    end

    status = DEFAULT_STATUSES.merge(action_desc[:status]||{})[result[:status]]

    respond_to do |format|
      format.json do
        if obj.nil?
          render_opts = { json: {errors: errors}, status: status }
          render_opts.reverse_merge!(action_desc[:error_render_opts]) if action_desc.has_key? :error_render_opts
        else
          render_opts = { json: obj, status: status }
          render_opts.reverse_merge!(action_desc[:object_render_opts]) if action_desc.has_key? :object_render_opts
        end

        render_opts.reverse_merge!(action_desc[:render_opts]) if action_desc.has_key? :render_opts
        render render_opts
      end
      format.html do
        result.each do |k,v|
          instance_variable_set("@#{k}", v)
        end
      end
    end
  end
end
setup_actions!(controller_name, klass, config) click to toggle source
# File lib/ddc/controller_builder.rb, line 62
def setup_actions!(controller_name, klass, config)
  actions = config[:actions]
  raise "Must specify actions" if actions.blank?

  actions.each do |action, action_desc|
    setup_action! controller_name, klass, action, action_desc, config
  end
end
setup_before_actions!(klass, config) click to toggle source
# File lib/ddc/controller_builder.rb, line 56
def setup_before_actions!(klass, config)
  (config[:before_actions] || []).each do |ba|
    klass.before_action ba
  end
end
specific_const_defined?(path) click to toggle source
# File lib/ddc/controller_builder.rb, line 22
def specific_const_defined?(path)
  path.split("::").inject(Object) do |mod, name|
    return unless mod.const_defined?(name, false)
    mod.const_get(name, false)
  end
  return true
end
specific_const_get(path) click to toggle source
# File lib/ddc/controller_builder.rb, line 30
def specific_const_get(path)
  path.split("::").inject(Object) do |mod, name|
    mod.const_get(name, false)
  end
end
specific_const_set(path, klass) click to toggle source
# File lib/ddc/controller_builder.rb, line 36
def specific_const_set(path, klass)
  path_pieces = path.split("::")
  mod_name = path_pieces[0..-2].join("::")
  mod = mod_name.present? ? Object.const_get(mod_name) : Object
  mod.const_set(path_pieces.last, klass)
end