Skip to content

Instantly share code, notes, and snippets.

@bantic
Last active September 9, 2022 12:22
Show Gist options
  • Save bantic/5688232 to your computer and use it in GitHub Desktop.
Save bantic/5688232 to your computer and use it in GitHub Desktop.
Programmatically list all routes (/paths) from within a rails app.
class RouteRecognizer
attr_reader :paths
# To use this inside your app, call:
# `RouteRecognizer.new.initial_path_segments`
# This returns an array, e.g.: ['assets','blog','team','faq','users']
INITIAL_SEGMENT_REGEX = %r{^\/([^\/\(:]+)}
def initialize
routes = Rails.application.routes.routes
@paths = routes.collect {|r| r.path.spec.to_s }
end
def initial_path_segments
@initial_path_segments ||= begin
paths.collect {|path| match_initial_path_segment(path)}.compact.uniq
end
end
def match_initial_path_segment(path)
if match = INITIAL_SEGMENT_REGEX.match(path)
match[1]
end
end
end
@sowenjub
Copy link

paths.collect {|path| match_initial_path_segment(path)}.compact.uniq
can be replaced with
paths.collect { |path| path[INITIAL_SEGMENT_REGEX, 1] }.compact.uniq

@drymar
Copy link

drymar commented Apr 29, 2020

@paths = routes.map {|r| r.defaults.merge(verb: r.verb) }.group_by { |r| r[:controller] } # would map more detailed routes list like:
{ '/somepath' => [{ controller: 'somepath', action: 'index', verb: 'GET', format: 'json' },
                  { controller: 'somepath', action: 'show', verb: 'GET', format: 'json' } ] }

@abevoelker
Copy link

This is great; I just made a couple tweaks to it for my use case.

class RouteChecker
  INITIAL_SEGMENT_REGEX = %r{^\/([^\/\(:]+)}

  def self.initial_path_segments
    @@paths ||= begin
      Set.new.tap do |s|
        Rails.application.routes.routes.each do |x|
          path = x.path.spec.to_s
          (match = INITIAL_SEGMENT_REGEX.match(path)) && s.add(match[1])
        end
      end
    end
  end

  def self.has_path?(x)
    self.initial_path_segments.include?(x)
  end
end
RouteChecker.has_path?("foo") # => true / false

@drymar
Copy link

drymar commented May 20, 2022

Looking great 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment