Skip to content
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

Merged
merged 4 commits into from May 23, 2019
Merged

Keep part when scope option has value #34656

merged 4 commits into from May 23, 2019

Conversation

albertoalmagro
Copy link
Contributor

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

@rails-bot rails-bot bot added the actionpack label Dec 8, 2018
@albertoalmagro
Copy link
Contributor Author

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, {}
Copy link
Member

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?
Copy link
Member

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?

Copy link
Contributor Author

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?.

@albertoalmagro
Copy link
Contributor Author

@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 👍

@albertoalmagro
Copy link
Contributor Author

@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.

@albertoalmagro
Copy link
Contributor Author

@gmcgibbon sorry I forgot to say it explicitly, this is ready for review. Could you please check it again? Thanks!

@albertoalmagro
Copy link
Contributor Author

@gmcgibbon Sorry for pinging you again. Does this need anything else?

Thanks!

Copy link
Member

@gmcgibbon gmcgibbon left a 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 = {
Copy link
Member

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.

@albertoalmagro
Copy link
Contributor Author

albertoalmagro commented Jan 12, 2019

@gmcgibbon thanks for your review! I've applied all your feedback:

  • CHANGELOG entry added to first commit.
  • Merged c40e6d9 into the first commit.
  • Fed mapping_params and route_params directly into the constructor.

Copy link
Member

@gmcgibbon gmcgibbon left a 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!

@gmcgibbon
Copy link
Member

Actually, one last thing. It would seem I'm wrong about ActionDispatch::Routing::Mapper being private API. We have to revert the kwarg change on that class.

@albertoalmagro
Copy link
Contributor Author

@gmcgibbon my commit message was wrong. It wasn't actually ActionDispatch::Routing::Mapper, but ActionDispatch::Routing::Mapper::Mapping. Which is private API.

Sorry for the confusion. I've changed my commit message, now everything should be good to go.

@gmcgibbon
Copy link
Member

@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

@albertoalmagro
Copy link
Contributor Author

Thanks! I've just rebased to fix a conflict on the CHANGELOG file.

@albertoalmagro
Copy link
Contributor Author

r? @rafaelfranca

@@ -7,7 +18,6 @@

*Edouard Chin*


Copy link
Member

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.

Copy link
Contributor Author

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 ❤️

@albertoalmagro
Copy link
Contributor Author

@rafaelfranca This is ready again, could you please review? Thanks

@albertoalmagro
Copy link
Contributor Author

Fixed conflicts in CHANGELOG. Could anyone please take a look at this? 🙏

@gmcgibbon gmcgibbon self-assigned this May 17, 2019
@gmcgibbon
Copy link
Member

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.

@albertoalmagro
Copy link
Contributor Author

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,
Copy link
Member

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.

Copy link
Member

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. 🤔

Copy link
Contributor Author

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.
Copy link
Member

@gmcgibbon gmcgibbon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@gmcgibbon gmcgibbon merged commit eba859d into rails:master May 23, 2019
@manueljacob
Copy link

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,
Copy link
Member

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.

Copy link
Member

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.

@rafaelfranca
Copy link
Member

@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

@deivid-rodriguez
Copy link
Contributor

@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 😃.

@gmcgibbon
Copy link
Member

gmcgibbon commented May 23, 2019

I believe fb9117e can be included in 6-0-stable. I don't see any breaking change besides the private API changes in other commits. Will backport.

We should look at making a test case for #12178 so we can validate it is fixed.

Backported in 85855d6.

goduchesne added a commit to hooktstudios/route_translator that referenced this pull request Jul 10, 2019
tagliala added a commit to enriclluelles/route_translator that referenced this pull request Jul 19, 2019
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
tagliala added a commit to enriclluelles/route_translator that referenced this pull request Jul 19, 2019
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
tagliala added a commit to enriclluelles/route_translator that referenced this pull request Jul 19, 2019
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
tagliala added a commit to enriclluelles/route_translator that referenced this pull request Jul 20, 2019
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
tagliala added a commit to enriclluelles/route_translator that referenced this pull request Jul 20, 2019
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Path helper picks up surrounding scope only if the URL has a parameter
6 participants