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
Keep part when scope option has value #34656
Keep part when scope option has value #34656
Conversation
r? @gmcgibbon |
@@ -51,13 +51,13 @@ def self.verb_matcher(verb) | |||
|
|||
def self.build(name, app, path, constraints, required_defaults, defaults) | |||
request_method_match = verb_matcher(constraints.delete(:request_method)) | |||
new name, app, path, constraints, required_defaults, defaults, request_method_match, 0 | |||
new name, app, path, constraints, required_defaults, defaults, request_method_match, 0, {} |
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 we can safely assume {}
by default for scope_options
. Also, I think we're far past the point of having too many positional arguments for this constructor (and Mapping
's constructor). We should look at using keyword args instead, but that can be done in another PR. They both seem to be private API so we don't need deprecation cycles.
@@ -67,7 +67,7 @@ def extract_parameterized_parts(route, options, recall, parameterize = nil) | |||
parameterized_parts = recall.merge(options) | |||
|
|||
keys_to_keep = route.parts.reverse_each.drop_while { |part| | |||
!options.key?(part) || (options[part] || recall[part]).nil? | |||
(!options.key?(part) && !value_for_optional_scope?(part, route, recall)) || (options[part] || recall[part]).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.
I find this hard to read. Maybe we can refactor, or space out the logic and add some comments?
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 was able to make the condition a little bit more simple and removed also the auxiliary method value_for_optional_scope?
.
@gmcgibbon Thanks for your review! Yes, I was also thinking about refactoring stuff here but wasn't sure if I should include it in another PR or within this one. My main concern was to have the commit that fixes the issue separated so it was clear what was fixing it. After having your opinion I think it makes sense to include some refactor improvements within this PR. I will submit them in separate commits and let you know when everything is ready for review again 👍 |
@gmcgibbon I've simplified a little bit the condition that fixes the bug by deleting the auxiliary method (it turned out that only first check was needed) and by simplifying boolean logic. I have squashed the changes for this fix but you can still compare both versions by checking the outdated comment above. Regarding refactorings, I've included three commits, each of them makes a different improvement. They are separate so it is clearer for you and for the commit history what was done. As you said, they could go in different PRs but I decided to take the opportunity to add them here so the PR in global results on a better patch. |
@gmcgibbon sorry I forgot to say it explicitly, this is ready for review. Could you please check it again? Thanks! |
@gmcgibbon Sorry for pinging you again. Does this need anything else? 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.
Sorry for the delay. Please add a changelog entry to the first commit. I would also opt to merge c40e6d9daa9a35e2f7f6dd500735f86eecb07be0 into the first commit too because its not a behaviour change, just syntax.
|
||
defaults = (scope[:defaults] || {}).dup | ||
scope_constraints = scope[:constraints] || {} | ||
mapping_params = { |
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.
Nitpick: mapping_params
could just b fed directly into the constructor here, same with route_params
below.
@gmcgibbon thanks for your review! I've applied all your feedback:
|
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.
Thanks for your patience. LGTM!
Actually, one last thing. It would seem I'm wrong about |
@gmcgibbon my commit message was wrong. It wasn't actually Sorry for the confusion. I've changed my commit message, now everything should be good to go. |
@albertoalmagro Thanks for clarifying. In that case, I agree this is good to go. Great work! I can only merge doc PRs so a core member needs to look this over before merging. cc @rafaelfranca |
Thanks! I've just rebased to fix a conflict on the |
actionpack/CHANGELOG.md
Outdated
@@ -7,7 +18,6 @@ | |||
|
|||
*Edouard Chin* | |||
|
|||
|
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 is intentional, please revert this line.
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.
My mistake! Didn't see that. Thanks @gmcgibbon for double checking ❤️
@rafaelfranca This is ready again, could you please review? Thanks |
Fixed conflicts in |
Sorry this is taking so long. I'm going to run this against an actual app and make sure we aren't introducing any regressions in terms of routing edge cases. |
Thanks @gmcgibbon, I appreciate it 🙂 |
@@ -50,14 +50,15 @@ def self.verb_matcher(verb) | |||
end | |||
|
|||
def self.build(name, app, path, constraints, required_defaults, defaults) | |||
request_method_match = verb_matcher(constraints.delete(:request_method)) | |||
new name, app, path, constraints, required_defaults, defaults, request_method_match, 0, {} | |||
new name: name, app: app, path: path, constraints: constraints, |
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.
Is there any worth changing new name, app, path, constraints, ...
to new name: name, app: app, path: path, constraints: constraints, ...
?
The self.build
still have the dependency of remember parameters'
positions, and the new name: name, app: app, path: path, constraints: constraints, ...
looks redundant to me.
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.
Good point. We should update self.build
to use keyword args too. We could even consider removing it, I don't see Route.build
used anywhere other than tests unless it is used somewhere else magically. 🤔
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.
Good catch @kamipo! As @gmcgibbon pointed out, Route.build
wasn't necessary. My last commit removes it. Thanks for your reviews guys ❤️
When a route was defined within an optional scope, if that route didn't take parameters the scope was lost when using path helpers. This patch ensures scope is kept both when the route takes parameters or when it doesn't. Fixes #33219
This commit changes from constructor's argument list to keyword arguments in order to remove the dependency of remember parameters' positions. The constructor already provided a default value for `internal`, this commits takes the chance to also add default values for `precedence` and `scope_options`.
…nstructor This commit changes from constructor's argument list to keyword arguments in order to remove the dependency of remember parameters' positions. It also unifies all parameters extracted from the `scope` into `scope_params`, which also takes care of providing the default values for them.
After @kamipo CR feedback we realized `Route#build` wasn't used. As it is also private API being able to create Routes both with `#new` and `#build` was redundant.
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.
👍
Thank you for implementing and merging this! @rafaelfranca I didn’t find out how the releasing procedure works exactly. What’s the first possible release which could include this fix? |
|
||
new set, ast, defaults, controller, default_action, scope[:module], to, formatted, scope_constraints, scope[:blocks] || [], via, options_constraints, anchor, options | ||
new set: set, ast: ast, controller: controller, default_action: default_action, |
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.
Is there any worth changing new set, ast, defaults, controller, default_action, ...
to new set: set, ast: ast, controller: controller, default_action: default_action, ...
?
The self.build still have the dependency of remember parameters'
positions, and the new set: set, ast: ast, controller: controller, default_action: default_action, ...
looks redundant to me.
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.
👍 We should grep for usage and submit a followup PR to address this.
@manueljacob Good question. @gmcgibbon do you see any breaking change on this commit or it is just a bug fix? If it is a bug fix we can include in 6-0-stable |
@albertoalmagro I'm curious whether this fixes #12178. Not that I care much these days, but it was the first issue I ever opened on Github 😃. |
PR rails/rails#34656 has recently been merged to rails master and backported to the rails 6-0-stable branch. It added an extra argument to the Mapper::Mapping.new method which makes it incompatible with the current version of route_translator This change is going to use `Mapper::Mapping.build` instead of `Mapper::Mapping.new` because the former preserved its signature across all Rails versions Fix: #195 Ref: rails/rails@85855d63fc
PR rails/rails#34656 has recently been merged to rails master and backported to the rails 6-0-stable branch. It added an extra argument to the Mapper::Mapping.new method which makes it incompatible with the current version of route_translator This change is going to use `Mapper::Mapping.build` instead of `Mapper::Mapping.new` because the former preserved its signature across all Rails versions Fix: #195 Ref: rails/rails@85855d63fc
PR rails/rails#34656 has recently been merged to rails master and backported to the rails 6-0-stable branch. It added an extra argument to the Mapper::Mapping.new method which makes it incompatible with the current version of route_translator This change is going to use `Mapper::Mapping.build` instead of `Mapper::Mapping.new` because the former preserved its signature across all Rails versions Fix: #195 Ref: rails/rails@85855d63fc
PR rails/rails#34656 has recently been merged to rails master and backported to the rails 6-0-stable branch. It added an extra argument to the Mapper::Mapping.new method which makes it incompatible with the current version of route_translator This change is going to use `Mapper::Mapping.build` instead of `Mapper::Mapping.new` because the former preserved its signature across all Rails versions Fix: #195 Ref: rails/rails@85855d63fc
PR rails/rails#34656 has recently been merged to rails master and backported to the rails 6-0-stable branch. It added an extra argument to the Mapper::Mapping.new method which makes it incompatible with the current version of route_translator This change is going to use `Mapper::Mapping.build` instead of `Mapper::Mapping.new` because the former preserved its signature across all Rails versions Fix: #195 Ref: rails/rails@85855d63fc
Summary
When a route was defined within an optional scope, if that route didn't take parameters the scope was lost when using path helpers. This patch ensures scope is kept both when the route takes parameters or when it doesn't.
Fixes #33219
r? @gmcgibbon