class Pakyow::Routing::Expansion

Expands a route template.

@api private

Attributes

controller[R]
expander[R]
name[R]

Public Class Methods

new(template_name, controller, options, &template_block) click to toggle source
Calls superclass method
# File lib/pakyow/routing/expansion.rb, line 17
def initialize(template_name, controller, options, &template_block)
  @controller = controller

  # Create the controller that stores available routes, groups, and namespaces.
  #
  @expander = Controller.make(set_const: false)

  # Evaluate the template to define available routes, groups, and namespaces.
  #
  instance_exec(**options, &template_block)

  # Define helper methods for routes
  #
  local_expander = @expander
  @expander.routes.each do |method, routes|
    routes.each do |route|
      unless @controller.singleton_class.instance_methods(false).include?(route.name)
        @controller.define_singleton_method route.name do |*args, &block|
          # Handle template parts named `new` by determining if we're calling `new` to expand
          # part of a template, or if we're intending to create a new controller instance.
          #
          # If args are empty we can be sure that we're creating a route.
          #
          if args.any?
            super(*args)
          else
            build_route(method, route.name, route.path || route.matcher, &block).tap do
              # Make sure the route was inserted in the same order as found in the template.
              #
              index_of_last_insert = local_expander.routes[method].index { |expander_route|
                expander_route.name == @routes[method].last.name
              }

              insert_before_this_index = @routes[method].select { |each_route|
                local_expander.routes[method].any? { |expander_route|
                  each_route.name == expander_route.name
                }
              }.map { |each_route|
                local_expander.routes[method].index { |expander_route|
                  expander_route.name == each_route.name
                }
              }.select { |index|
                index > index_of_last_insert
              }.first

              if insert_before_this_index
                @routes[method].insert(
                  @routes[method].index { |each_route|
                    each_route.name == local_expander.routes[method][insert_before_this_index].name
                  }, @routes[method].delete_at(index_of_last_insert)
                )
              end
            end
          end
        end
      end
    end
  end

  # Define helper methods for groups and namespaces
  #
  @expander.children.each do |child|
    unless @controller.singleton_class.instance_methods(false).include?(child.__object_name.name)
      @controller.define_singleton_method child.__object_name.name do |&block|
        if child.path.nil?
          group(child.__object_name.name, &block)
        else
          namespace(child.__object_name.name, child.path || child.matcher, &block)
        end
      end
    end
  end

  # Set the expansion on the controller.
  #
  @controller.expansions << template_name
end

Public Instance Methods

group(*args, **kwargs, &block) click to toggle source
# File lib/pakyow/routing/expansion.rb, line 95
def group(*args, **kwargs, &block)
  @expander.send(:group, *args, set_const: false, **kwargs, &block)
end
namespace(*args, **kwargs, &block) click to toggle source
# File lib/pakyow/routing/expansion.rb, line 99
def namespace(*args, **kwargs, &block)
  @expander.send(:namespace, *args, set_const: false, **kwargs, &block)
end