lib/active_admin/router.rb
# frozen_string_literal: true
module ActiveAdmin
# @private
class Router
attr_reader :namespaces, :router
def initialize(router:, namespaces:)
@router = router
@namespaces = namespaces
end
def apply
define_root_routes
define_resources_routes
end
private
def define_root_routes
namespaces.each do |namespace|
if namespace.root?
router.root namespace.root_to_options.merge(to: namespace.root_to)
else
router.namespace namespace.name, namespace.route_options.dup do
router.root namespace.root_to_options.merge(to: namespace.root_to, as: :root)
end
end
end
end
# Defines the routes for each resource
def define_resources_routes
resources = namespaces.flat_map { |n| n.resources.values }
resources.each do |config|
define_resource_routes(config)
end
end
def define_resource_routes(config)
if config.namespace.root?
define_routes(config)
else
# Add on the namespace if required
define_namespace(config)
end
end
def define_routes(config)
if config.belongs_to?
define_belongs_to_routes(config)
else
page_or_resource_routes(config)
end
end
def page_or_resource_routes(config)
config.is_a?(Page) ? page_routes(config) : resource_routes(config)
end
def resource_routes(config)
router.resources config.resource_name.route_key, only: config.defined_actions do
define_actions(config)
end
end
def page_routes(config)
page = config.underscored_resource_name
router.get "/#{page}" => "#{page}#index"
config.page_actions.each do |action|
Array.wrap(action.http_verb).each do |verb|
build_route(verb, "/#{page}/#{action.name}" => "#{page}##{action.name}")
end
end
end
# Defines member and collection actions
def define_actions(config)
router.member do
config.member_actions.each { |action| build_action(action) }
end
router.collection do
config.collection_actions.each { |action| build_action(action) }
router.post :batch_action if config.batch_actions_enabled?
end
end
# Deals with +ControllerAction+ instances
# Builds one route for each HTTP verb passed in
def build_action(action)
build_route(action.http_verb, action.name)
end
def build_route(verbs, *args)
Array.wrap(verbs).each { |verb| router.send(verb, *args) }
end
def define_belongs_to_routes(config)
# If it's optional, make the normal resource routes
page_or_resource_routes(config) if config.belongs_to_config.optional?
# Make the nested belongs_to routes
# :only is set to nothing so that we don't clobber any existing routes on the resource
router.resources config.belongs_to_config.target.resource_name.plural, only: [] do
page_or_resource_routes(config)
end
end
def define_namespace(config)
router.namespace config.namespace.name, config.namespace.route_options.dup do
define_routes(config)
end
end
end
end