class Chusaku::Routes

Handles extracting information about the Rails project's routes.

Public Class Methods

call() click to toggle source

Primary method to call.

Example output:

{
  'users' => {
    'edit' => [
      { verb: 'GET', path: '/users/:id', name: 'edit_user' }
    ],
    'update' => [
      { verb: 'PATCH', path: '/users', name: 'edit_user' },
      { verb: 'PUT', path: '/users', name: 'edit_user' }
    ]
  },
  'empanadas' => {
    'create' => [
      { verb: 'POST', path: '/empanadas', name: nil }
    ]
  }
}

@return [Hash] Routes hash

# File lib/chusaku/routes.rb, line 29
def call
  routes = {}

  Rails.application.routes.routes.each do |route|
    controller, action, defaults = extract_data_from(route)
    routes[controller] ||= {}
    routes[controller][action] ||= []

    add_info_for \
      route: route,
      routes: routes,
      controller: controller,
      action: action,
      defaults: defaults
  end

  backfill_routes(routes)
end

Private Class Methods

add_info_for(route:, routes:, controller:, action:, defaults:) click to toggle source

Adds formatted route info for the given param combination.

@param route [Hash] Route info @param routes [Hash] Collection of all route info @param controller [String] Controller key @param action [String] Action key @param defaults [Hash] Default parameters for route @return [void]

# File lib/chusaku/routes.rb, line 58
def add_info_for(route:, routes:, controller:, action:, defaults:)
  verbs_for(route).each do |verb|
    routes[controller][action]
      .push(format(route: route, verb: verb, defaults: defaults))
    routes[controller][action].uniq!
  end
end
backfill_routes(routes) click to toggle source

Given a routes hash, backfill entries that aren't already filled by `Rails.application.routes`.

@param routes [Hash] Routes hash generated by this class @return [Hash] Backfilled routes hash

# File lib/chusaku/routes.rb, line 100
def backfill_routes(routes)
  paths = {}

  routes.each do |_controller, actions|
    actions.each do |_action, data|
      data.each do |datum|
        paths[datum[:path]] ||= datum[:name]
        datum[:name] ||= paths[datum[:path]]
      end
    end
  end

  routes
end
extract_data_from(route) click to toggle source

Given a route, extract the controller and action strings.

@param route [ActionDispatch::Journey::Route] Route instance @return [Array<Object>] (String, String, Hash)

# File lib/chusaku/routes.rb, line 119
def extract_data_from(route)
  defaults = route.defaults.dup
  controller = defaults.delete(:controller)
  action = defaults.delete(:action)

  [controller, action, defaults]
end
format(route:, verb:, defaults:) click to toggle source

Formats information for a given route.

@param route [ActionDispatch::Journey::Route] Route given by Rails @param verb [String] HTTP verb @param defaults [Hash] Default parameters for route @return [Hash] { verb => String, path => String, name => String }

# File lib/chusaku/routes.rb, line 86
def format(route:, verb:, defaults:)
  {
    verb: verb,
    path: route.path.spec.to_s.gsub('(.:format)', ''),
    name: route.name,
    defaults: defaults
  }
end
verbs_for(route) click to toggle source

Extract the HTTP verbs for a Rails route. Required for older versions of Rails that return regular expressions for a route verb which sometimes contains multiple verbs.

@param route [ActionDispatch::Journey::Route] Route given by Rails @return [Array<String>] List of HTTP verbs for the given route

# File lib/chusaku/routes.rb, line 72
def verbs_for(route)
  route_verb = route.verb.to_s

  %w[GET POST PUT PATCH DELETE].select do |verb|
    route_verb.include?(verb)
  end
end