In Browser Path Matching with Javascript #9001

Merged
merged 1 commit into from Jan 21, 2013

Projects

None yet
@schneems
Member

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:

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.

To newcomers: you can run this route page in Rails 3.2 (without this feature), using Sextant.

It has also been noted that this PR is: OVER 9000.

ATP actionpack

@mdespuits
Contributor

Wow. Just Wow. 👍

@Jauny
Jauny commented Jan 19, 2013

yea just wow, amazing 👍

@Antiarchitect
Contributor

Like! 👍

@frodsan
Contributor
frodsan commented Jan 19, 2013

Awesome 👍

@MadRabbit

$ rails routes | grep foo

but generally looks like fun :)

@h3h
h3h commented Jan 19, 2013

👍

@h3h h3h commented on an outdated diff Jan 19, 2013
..._dispatch/middleware/templates/routes/_table.html.erb
@@ -52,5 +88,60 @@
});
}
+ // takes an array of elements with a data-regex attribute and
+ // passes their their parent <tr> into the callback function
+ // if the regex matchs a given path
+ function eachElemsForPath(elems, path, func) {
+ each(elems, function(e){
+ var reg = e.getAttribute("data-regex");
+ if (path.match(RegExp(reg))) {
+ func(e.parentNode.cloneNode(true));
+ }
+ })
+ }
+
+ // Ensure path always starts with a slash "/" and remove params or fragments
+ function sanatizePath(path) {
@h3h
h3h Jan 19, 2013

sanitizePath for the greater spelling win. 😄

@goshakkk
Contributor

👍

@Jacke
Jacke commented Jan 19, 2013

👍 Awesome!!

@drnic
Contributor
drnic commented Jan 19, 2013

A very appropriate PR for #9001!

@aviflombaum

dude, killer. 👍 its like better_errors for routes :-)

@jrgifford
Contributor

does this work in production? That's the only question I have. (i will admit i haven't looked at the code for this.)

@schneems
Member

@jrgifford you cannot access this url in production, it is in an internal controller only added in development, and there is a before filter that will prevent anyone from accessing this page unless it is a local request.

@shedd
shedd commented Jan 19, 2013

Fantastic idea!

@hankblinq

Clap Clap Clap!

@jrgifford
Contributor

@schneems ah, ok. excellent!

@mmay
mmay commented Jan 20, 2013

👍

@thenickcox
Contributor

Here's to hoping we use the ability to use animated GIFs in pull requests for good, not for annoying.

@codeblooded

👍 Yeah!!!

@BMorearty
Contributor

❤️

@jfairchild

👍

@jgaskins
Contributor

@drnic This PR is, indeed, over 9000.

@pacoguzman
Contributor

🤘

@pixeltrix pixeltrix and 2 others commented on an outdated diff Jan 20, 2013
actionpack/lib/action_dispatch/routing/inspector.rb
@@ -3,6 +3,12 @@
module ActionDispatch
module Routing
class RouteWrapper < SimpleDelegator
+
+ def initialize(route)
+ @route = route
+ super(@route)
+ end
+
@pixeltrix
pixeltrix Jan 20, 2013 Member

I assume that you're capturing the route for the regex method below? If so can't we delete this method and implement regex like this:

def regex
  __get_object__.path.to_regexp
end

Also can we keep the names consistent - use regexp instead of regex.

@schneems
schneems Jan 20, 2013 Member

thanks, i had never worked with SimpleDelegator before, looks like it's __getobj__

@carlosantoniodasilva carlosantoniodasilva commented on an outdated diff Jan 20, 2013
..._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 td {
+ padding: 0 30px;
+ }
+
+ #route_table {
+ margin: 0 auto 0;
@carlosantoniodasilva
carlosantoniodasilva Jan 20, 2013 Member

two spaces after :. Also move this #route_table definition above the other one (as the first one).

@carlosantoniodasilva carlosantoniodasilva commented on an outdated diff Jan 20, 2013
..._dispatch/middleware/templates/routes/_table.html.erb
+ #route_table {
+ margin: 0 auto 0;
+ border-collapse: collapse;
+ }
+
+ #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 ;
@carlosantoniodasilva
carlosantoniodasilva Jan 20, 2013 Member

Wrong indent, space before ;.

@carlosantoniodasilva carlosantoniodasilva commented on an outdated diff Jan 20, 2013
..._dispatch/middleware/templates/routes/_table.html.erb
+ #route_table td {
+ padding: 0 30px;
+ }
+
+ #route_table {
+ margin: 0 auto 0;
+ border-collapse: collapse;
+ }
+
+ #route_table tr.bottom th {
+ padding-bottom: 10px;
+ line-height: 15px;
+ }
+
+ #route_table .matched_paths {
+ background-color: LightGoldenRodYellow ;
@carlosantoniodasilva
carlosantoniodasilva Jan 20, 2013 Member

Wrong indent, space before ;.

@carlosantoniodasilva carlosantoniodasilva commented on the diff Jan 20, 2013
..._dispatch/middleware/templates/routes/_table.html.erb
</tr>
</thead>
+ <tbody class='matched_paths' id='matched_paths'>
+ </tbody>
@carlosantoniodasilva carlosantoniodasilva commented on an outdated diff Jan 20, 2013
..._dispatch/middleware/templates/routes/_table.html.erb
+ if (path.match(RegExp(reg))) {
+ func(e.parentNode.cloneNode(true));
+ }
+ })
+ }
+
+ // Ensure path always starts with a slash "/" and remove params or fragments
+ function sanitizePath(path) {
+ var path = path.charAt(0) == '/' ? path : "/" + path
+ return path.replace(/\#.*|\?.*/, '')
+ }
+
+ // Enables path search functionality
+ function setupMatchPaths() {
+ var regex_elems = document.querySelectorAll('#route_table [data-regex]');
+ var path_elem = document.querySelector('#path_search')
@carlosantoniodasilva
carlosantoniodasilva Jan 20, 2013 Member

No ; at the end.

@carlosantoniodasilva carlosantoniodasilva and 2 others commented on an outdated diff Jan 20, 2013
..._dispatch/middleware/templates/routes/_table.html.erb
+ }
+ })
+ }
+
+ // Ensure path always starts with a slash "/" and remove params or fragments
+ function sanitizePath(path) {
+ var path = path.charAt(0) == '/' ? path : "/" + path
+ return path.replace(/\#.*|\?.*/, '')
+ }
+
+ // Enables path search functionality
+ function setupMatchPaths() {
+ var regex_elems = document.querySelectorAll('#route_table [data-regex]');
+ var path_elem = document.querySelector('#path_search')
+ var selected_section = document.querySelector('#matched_paths');
+ var no_match_text = '<tr><th colspan="4">None</th></tr>';
@carlosantoniodasilva
carlosantoniodasilva Jan 20, 2013 Member

Actually you could use one var declaration only.

@carlosantoniodasilva
carlosantoniodasilva Jan 20, 2013 Member

And change variables names to be camelCase.

@schneems
schneems Jan 20, 2013 Member

It's not often that I get the opportunity to refactor javascript code... can you give me more information by what you mean by only using one var declaration?

@schneems
Member

Updated, please review latest code.

@steveklabnik
Member

Can't be auto-merged

@schneems
Member

CHANGELOG!!!!!!!!!!!!!! (said Star Trek II style). I pushed an update. I wish GH would make the merge-ability of a PR public info.

@agis-
Contributor
agis- commented Jan 20, 2013

Oh my this is awesome!

@vendethiel

This is over nine thousands.

@vendethiel vendethiel and 1 other commented on an outdated diff Jan 20, 2013
..._dispatch/middleware/templates/routes/_table.html.erb
@@ -25,7 +61,7 @@
<script type='text/javascript'>
function each(elems, func) {
if (!elems instanceof Array) { elems = [elems]; }
- for (var i = elems.length; i--; ) {
+ for (var i = 0; i < elems.length; i++) {
@vendethiel
vendethiel Jan 20, 2013

you'd like to cache it for best performances, ie for (var i = 0, len = elems.length; i < len; i++)

@schneems
schneems Jan 21, 2013 Member

thanks @Nami-Doc, updated.

@chocoby
Contributor
chocoby commented Jan 21, 2013

👍

@samqiu
samqiu commented Jan 21, 2013

You are awesome!

@rafaelfranca rafaelfranca and 1 other commented on an outdated diff Jan 21, 2013
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
@rafaelfranca
rafaelfranca Jan 21, 2013 Member
*Richard Schneeman*
@rafaelfranca rafaelfranca and 1 other commented on an outdated diff Jan 21, 2013
actionpack/lib/action_dispatch/routing/inspector.rb
@@ -34,6 +34,14 @@ def name
super.to_s
end
+ def regexp
+ __getobj__.path.to_regexp
+ end
+
+ def json_regexp
+ Regexp.new(regexp.inspect.sub('\\A','^').sub('\\Z','$').sub('\\z','$').sub(/^\//,'').sub(/\/[a-z]*$/,'').gsub(/\(\?#.+\)/, '').gsub(/\(\?-\w+:/,'(').gsub(/\s/,'')).source
@rafaelfranca
rafaelfranca Jan 21, 2013 Member

Would be good to break this line and also use spaces before after the ,

@schneems
schneems Jan 21, 2013 Member

updated and using a var for clarity.

@schneems schneems 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
8b72d68
@rafaelfranca rafaelfranca merged commit 68a6fb6 into rails:master Jan 21, 2013
@rafaelfranca
Member

❤️ 💚 💙 💛 💜

@calebthompson
Contributor

@schneems What did you use to make the gif?

@kuraga
kuraga commented on 8b72d68 Jan 21, 2013

👎 I think info pages should provide minimal information only.

Contributor

I think this is good.
Right now I am just using rake routes and it is slow

et replied Jan 24, 2013

@kuraga - little things like this go a long way to keep developers happy. Happy developers are what keep the framework thriving.
It would be nice if the inline javascripts and stylesheets are cleaned up to external assets as it seems like a long step backwards, but this looks to match the rest of templates implementations.
@schneems - thanks for your work. This is great stuff.

To get this feature on non Rails 4 versions, install schneem's gem, Sextant

Contributor

@eric-hu Thanks!

@brandonblack

very nice

@iampeter

👍

@flexoid
Contributor
flexoid commented Jan 24, 2013

That's just awesome! 👍

@miguelff

Awesome! ❤️

@pedrosnk

lovely

@sir-pinecone

👍 👍 👍

@bsodmike
Contributor

Dude @schneems ❤️ .... 👍 👍

@tkbeili
tkbeili commented Jan 24, 2013

👍

@ravidsrk

Awesome stuff <3

@owebmaster

awesome! 😍

@wesleychang

Awesome!!!

@camsong
Contributor
camsong commented Jan 25, 2013

Amazing 👍

@wizztjh
wizztjh commented Jan 25, 2013

+1

@jwo jwo referenced this pull request in mperham/sidekiq Jan 25, 2013
Closed

Matrix Style Log Formatter #646

@hujinpu
hujinpu commented Jan 25, 2013

Nice feature!

@jankeesvw
Contributor

Nice work! 👍

@ahmet
ahmet commented Jan 25, 2013

Nice 👍

@jipiboily
Contributor

❤️

@josin
josin commented Jan 25, 2013

Good job! 👍

@passion8
Contributor

very good job,thanks
👍

@peppyheppy

👍 I like. (the gif and the PR)

@FUT
FUT commented Jan 28, 2013

great!

@ehrktia
ehrktia commented Jan 29, 2013

amazed

@djbender

👍

@tubbo
tubbo commented Jan 29, 2013

love it, but what happens if i want to do rails g resource rails? i wanna be meta!!1 ;-) :shipit:

@ghost
ghost commented Jan 30, 2013

tumblr_ma97kgGJmQ1qft9ueo1_500

@rahul100885
Contributor

Just awesome

@krishnasrihari

Awesome

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