From 8b72d689e3df55c5e6995a637436486f0837dc8e Mon Sep 17 00:00:00 2001 From: schneems Date: Fri, 18 Jan 2013 15:18:23 -0600 Subject: [PATCH] In Browser Path Matching with Javascript When debugging routes ,it can sometimes be difficult to understand exactly how the paths are matched. This PR adds a JS based path matching widget to the `/rails/info/routes` output. You can enter in a path, and it will tell you which of the routes that path matches, while preserving order (top match wins). The matching widget in action: ![](http://f.cl.ly/items/3A2F0v2m3m1Z1p3P3O3k/path-match.gif) Prior to this PR the only way to check matching paths is via mental math, or typing in a path in the url bar and seeing where it goes. This feature will be an invaluable debugging tool by dramatically decreasing the time needed to check a path match. ATP actionpack --- actionpack/CHANGELOG.md | 5 + .../templates/routes/_route.html.erb | 2 +- .../templates/routes/_table.html.erb | 110 ++++++++++++++++-- .../lib/action_dispatch/routing/inspector.rb | 23 +++- .../test/dispatch/routing/inspector_test.rb | 8 ++ 5 files changed, 135 insertions(+), 13 deletions(-) diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index 3b2b1330fc..7309d42f17 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,5 +1,10 @@ ## Rails 4.0.0 (unreleased) ## +* Add javascript based routing path matcher to `/rails/info/routes`. + Routes can now be filtered by whether or not they match a path. + + *Richard Schneeman* + * Given params.permit(:name) diff --git a/actionpack/lib/action_dispatch/middleware/templates/routes/_route.html.erb b/actionpack/lib/action_dispatch/middleware/templates/routes/_route.html.erb index 400ae97d22..24e44f31ac 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/routes/_route.html.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/routes/_route.html.erb @@ -7,7 +7,7 @@ <%= route[:verb] %> - + <%= route[:path] %> diff --git a/actionpack/lib/action_dispatch/middleware/templates/routes/_table.html.erb b/actionpack/lib/action_dispatch/middleware/templates/routes/_table.html.erb index 9026c4eeb2..95461fa693 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/routes/_table.html.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/routes/_table.html.erb @@ -1,22 +1,58 @@ <% content_for :style do %> - #route_table td { padding: 0 30px; } - #route_table { margin: 0 auto 0; } + #route_table { + margin: 0 auto 0; + border-collapse: collapse; + } + + #route_table td { + padding: 0 30px; + } + + #route_table tr.bottom th { + padding-bottom: 10px; + line-height: 15px; + } + + #route_table .matched_paths { + background-color: LightGoldenRodYellow; + } + + #route_table .matched_paths { + border-bottom: solid 3px SlateGrey; + } + + #path_search { + width: 80%; + font-size: inherit; + } <% end %> - + + + + + + + + + <%= yield %> @@ -25,7 +61,7 @@ diff --git a/actionpack/lib/action_dispatch/routing/inspector.rb b/actionpack/lib/action_dispatch/routing/inspector.rb index 6c970f3024..bc6dd7145c 100644 --- a/actionpack/lib/action_dispatch/routing/inspector.rb +++ b/actionpack/lib/action_dispatch/routing/inspector.rb @@ -34,6 +34,23 @@ module ActionDispatch super.to_s end + def regexp + __getobj__.path.to_regexp + end + + def json_regexp + str = regexp.inspect. + sub('\\A' , '^'). + sub('\\Z' , '$'). + sub('\\z' , '$'). + sub(/^\// , ''). + sub(/\/[a-z]*$/ , ''). + gsub(/\(\?#.+\)/ , ''). + gsub(/\(\?-\w+:/ , '('). + gsub(/\s/ , '') + Regexp.new(str).source + end + def reqs @reqs ||= begin reqs = endpoint @@ -101,7 +118,11 @@ module ActionDispatch end.collect do |route| collect_engine_routes(route) - { name: route.name, verb: route.verb, path: route.path, reqs: route.reqs } + { name: route.name, + verb: route.verb, + path: route.path, + reqs: route.reqs, + regexp: route.json_regexp } end end diff --git a/actionpack/test/dispatch/routing/inspector_test.rb b/actionpack/test/dispatch/routing/inspector_test.rb index c7dcb5a683..55221f87c4 100644 --- a/actionpack/test/dispatch/routing/inspector_test.rb +++ b/actionpack/test/dispatch/routing/inspector_test.rb @@ -21,6 +21,14 @@ module ActionDispatch inspector.format(ActionDispatch::Routing::ConsoleFormatter.new, options[:filter]).split("\n") end + def test_json_regexp_converter + @set.draw do + get '/cart', :to => 'cart#show' + end + route = ActionDispatch::Routing::RouteWrapper.new(@set.routes.first) + assert_equal "^\\/cart(?:\\.([^\\/.?]+))?$", route.json_regexp + end + def test_displaying_routes_for_engines engine = Class.new(Rails::Engine) do def self.inspect
Helper
- <%= link_to "Path", "#", 'data-route-helper' => '_path', - title: "Returns a relative path (without the http or domain)" %> / - <%= link_to "Url", "#", 'data-route-helper' => '_url', - title: "Returns an absolute url (with the http and domain)" %> -
Helper HTTP Verb Path Controller#Action
<%# Helper %> + <%= link_to "Path", "#", 'data-route-helper' => '_path', + title: "Returns a relative path (without the http or domain)" %> / + <%= link_to "Url", "#", 'data-route-helper' => '_url', + title: "Returns an absolute url (with the http and domain)" %> + <%# HTTP Verb %> + <%# Path %> + <%= search_field(:path, nil, id: 'path_search', placeholder: "Path Match") %> + <%# Controller#action %> +