-
Notifications
You must be signed in to change notification settings - Fork 22.2k
Mapper with keywords #52512
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mapper with keywords #52512
Conversation
9ae462c to
29f5205
Compare
tenderlove
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems good, just a couple questions.
| options.delete(app) if app | ||
| hash_key_app = true | ||
| end | ||
| def mount(app, as: nil, via: nil, at: nil, defaults: nil, constraints: nil, anchor: false, format: false, path: nil, internal: nil, **mapping, &block) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is **mapping? A method call to something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mapping is route mapping parameters as a keyword splat like:
rails/actionpack/lib/action_dispatch/routing.rb
Lines 133 to 137 in 9ba208c
| # get '/articles/:year/:month/:day', to: 'articles#find_by_id', constraints: { | |
| # year: /\d{4}/, | |
| # month: /\d{1,2}/, | |
| # day: /\d{1,2}/ | |
| # } |
To be honest, I'm not familiar with this usage outside of constraints. We might want to deprecate this too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah actually I think this is just a shorthand for constraints:
rails/actionpack/test/controller/routing_test.rb
Lines 566 to 567 in 9ba208c
| get "page/:year/:month/:day/:title", to: "page#show", as: "article", | |
| year: /\d+/, month: /\d+/, day: /\d+/ |
These params get passed down to the route that gets built too, which they might not need to be:
| options = ast.wildcard_options.merge!(options) |
I'll dig a little deeper and see what's going on with this usage. Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I can tell, strings passed as mapper parameters are treated as route defaults, and regexes are constraints for route parameters. I vote to deprecate this since there's already keywords for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I can try to deal with mapping parameter deprecations above in a future PR. I need to introduce keywords in resource calls too which could be done as a followup or now.
| get "/c/:id", as: :collision, to: "collision#show" | ||
| get "/collision", to: "collision#show" | ||
| get "/no_collision", to: "collision#show", as: nil | ||
| get "/no_collision", to: "collision#show", as: false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might be a regression. The previous behaviour is get "/no_collision", to: "collision#show", as: nil wouldn't name the route and now it will because keyword defaults are nil.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in the latest commit. I don't like this usage either IMO so I'd like to deprecate this behaviour too IMO.
|
We can't merge this one right? We can't remove behavior that we just deprecated. We can only merge this after Rails 8.0 is released. |
Correct. I might be able to make it work without removing the deprecations so we can get the benefits sooner. It might look weird, so I'll take a look. |
29f5205 to
be8d9ff
Compare
|
There, this should now be mergable today. The deprecations added can be removed in the next release to clean up the router. Main: This branch: Same-ish difference with the deprecations re-added and the regression above patched. |
be8d9ff to
214022e
Compare
Converts hashes to keywords in ActionDispatch::Routing::Mapper. This makes the mapper a little easier to reason about, and slightly faster.
518478c to
6be2367
Compare
| raise ArgumentError, "Route path not specified" if path.nil? | ||
|
|
||
| def match(*path_or_actions, as: DEFAULT, via: nil, to: nil, controller: nil, action: nil, on: nil, defaults: nil, constraints: nil, anchor: nil, format: nil, path: nil, internal: nil, **mapping, &block) | ||
| if path_or_actions.count > 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the conditional here matches what the previous code was doing and the deprecation inside doesn't seem to match having multiple actions specified (which I'm also not clear on whether that should even be deprecated).
Motivation / Background
Followup #52422
Detail
This Pull Request changes the routing mapper to use keywords instead of hashes in most places, which results in a slight speed boost, and clearer code.
Additional information
Using the benchmark in the initial deprecation PR:
Before:
After:
It turns out the real speed difference is next to nothing, which is unfortunate. There was a bug in my initial implementation that made it faster 🤦. However, I think now that the mapper is easier to reason about, we should be able to do see optimization potential a little bit easier. I can see two in the scopes and AST parsing that I'll work on next.
Checklist
Before submitting the PR make sure the following are checked:
[Fix #issue-number]