aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--railties/lib/rails/application/route_inspector.rb101
1 files changed, 69 insertions, 32 deletions
diff --git a/railties/lib/rails/application/route_inspector.rb b/railties/lib/rails/application/route_inspector.rb
index 3e08b78221..5ca366c5f2 100644
--- a/railties/lib/rails/application/route_inspector.rb
+++ b/railties/lib/rails/application/route_inspector.rb
@@ -1,5 +1,64 @@
+require 'delegate'
+
module Rails
class Application
+ class RouteWrapper < SimpleDelegator
+ def endpoint
+ rack_app ? rack_app.inspect : "#{controller}##{action}"
+ end
+
+ def constraints
+ requirements.except(:controller, :action)
+ end
+
+ def rack_app(app = self.app)
+ @rack_app ||= begin
+ class_name = app.class.name.to_s
+ if class_name == "ActionDispatch::Routing::Mapper::Constraints"
+ rack_app(app.app)
+ elsif class_name !~ /^ActionDispatch::Routing/
+ app
+ end
+ end
+ end
+
+ def verb
+ super.source.gsub(/[$^]/, '')
+ end
+
+ def path
+ super.spec.to_s
+ end
+
+ def name
+ super.to_s
+ end
+
+ def reqs
+ @reqs ||= begin
+ reqs = endpoint
+ reqs += " #{constraints.inspect}" unless constraints.empty?
+ reqs
+ end
+ end
+
+ def controller
+ requirements[:controller] || ':controller'
+ end
+
+ def action
+ requirements[:action] || ':action'
+ end
+
+ def internal?
+ path =~ %r{/rails/info/properties|^/assets}
+ end
+
+ def engine?
+ rack_app && rack_app.respond_to?(:routes)
+ end
+ end
+
##
# This class is just used for displaying route information when someone
# executes `rake routes`. People should not use this class.
@@ -21,35 +80,22 @@ module Rails
def collect_routes(routes)
routes = routes.collect do |route|
- route_reqs = route.requirements
-
- rack_app = discover_rack_app(route.app)
-
- controller = route_reqs[:controller] || ':controller'
- action = route_reqs[:action] || ':action'
+ RouteWrapper.new(route)
+ end.reject do |route|
+ route.internal?
+ end.collect do |route|
+ collect_engine_routes(route)
- endpoint = rack_app ? rack_app.inspect : "#{controller}##{action}"
- constraints = route_reqs.except(:controller, :action)
-
- reqs = endpoint
- reqs += " #{constraints.inspect}" unless constraints.empty?
-
- verb = route.verb.source.gsub(/[$^]/, '')
-
- collect_engine_routes(reqs, rack_app)
-
- {:name => route.name.to_s, :verb => verb, :path => route.path.spec.to_s, :reqs => reqs }
+ {:name => route.name, :verb => route.verb, :path => route.path, :reqs => route.reqs }
end
-
- # Skip the route if it's internal info route
- routes.reject { |r| r[:path] =~ %r{/rails/info/properties|^/assets} }
end
- def collect_engine_routes(name, rack_app)
- return unless rack_app && rack_app.respond_to?(:routes)
+ def collect_engine_routes(route)
+ name = route.endpoint
+ return unless route.engine?
return if @engines[name]
- routes = rack_app.routes
+ routes = route.rack_app.routes
if routes.is_a?(ActionDispatch::Routing::RouteSet)
@engines[name] = collect_routes(routes.routes)
end
@@ -70,15 +116,6 @@ module Rails
"#{r[:name].rjust(name_width)} #{r[:verb].ljust(verb_width)} #{r[:path].ljust(path_width)} #{r[:reqs]}"
end
end
-
- def discover_rack_app(app)
- class_name = app.class.name.to_s
- if class_name == "ActionDispatch::Routing::Mapper::Constraints"
- discover_rack_app(app.app)
- elsif class_name !~ /^ActionDispatch::Routing/
- app
- end
- end
end
end
end