-
Notifications
You must be signed in to change notification settings - Fork 21.4k
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
Avoid passing {format:nil} from form_for/form_with to polymorphic_path #43766
Avoid passing {format:nil} from form_for/form_with to polymorphic_path #43766
Conversation
9a8f52d
to
f5cb993
Compare
…to form_with, this could potentially cause some regress, as the condition to send polymorphic_path(record, {}) instead of polymorphic_path(record, format: options.delete(:format)) is removed and when format is not passed, this causes issues if the caller is not expecting an extra arg format:nil. This PR adds back the condition inside for with and add a test to make sure it doesn't break for_with
8e5feee
to
c92ac83
Compare
@@ -754,7 +754,11 @@ def form_with(model: nil, scope: nil, url: nil, format: nil, **options, &block) | |||
|
|||
if model | |||
if url != false | |||
url ||= polymorphic_path(model, format: format) | |||
url ||= if format.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.
Should this behave differently if called as form_with(format: nil)
instead of form_with()
(without a format?). It looks like the old code in was using options.key?
and options.delete
IMO it seems fine that format: nil
is the same as unspecified, but if that has a difference to polymorphic_path maybe it is significant.
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.
IMO it seems fine that format: nil is the same as unspecified, but if that has a difference to polymorphic_path maybe it is significant.
Personally I think it should be fine given that the only real usage of the format:nil
within polymorphic_path
(via method polymorphic_method
) is it being passed on as part of options
to the method
:
if options.empty?
recipient.public_send(method, *args)
else
recipient.public_send(method, *args, options)
end
I think most likely the method
itself can handle the difference between format:nil
vs format not specified, as format:nil
isn't a meaningful thing to pass on... and there is likely a default value if a method is expecting a format
.
@@ -754,7 +754,11 @@ def form_with(model: nil, scope: nil, url: nil, format: nil, **options, &block) | |||
|
|||
if model | |||
if url != false | |||
url ||= polymorphic_path(model, format: format) |
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 curious to see if we could implement this as polymorphic_path(model, { format: format }.compact)
.
But then I noticed that I can't get the test to fail if I change the code back to the version before this PR. @cryptoque can you double-check the test to see if it needs tweaking?
3.0.2 ~/code/rails/actionview main *= bin/test test/template/form_helper_test.rb -n /new_form_for_without_format/
Running 305 tests in parallel using 8 processes
Run options: -n /new_form_for_without_format/ --seed 41714
# Running:
.
Finished in 0.204844s, 4.8818 runs/s, 4.8818 assertions/s.
1 runs, 1 assertions, 0 failures, 0 errors, 0 skips
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.
@kaspth that is good point, I will modify the test on Monday.
Summary
In #43421 part of the functionalities of
form_for
was delegated toform_with
, this could potentially cause some issues in that the following code inform_for
:is removed and replace with functionality inside
form_with
:This caused some noticeable issues in the latest rails upgrade for GitHub. As when
format
is not passed,polymorphic_path(model, {format: nil})
is called instead of the originalpolymorphic_path(model, {})
andand the extra
options
inrecipient.public_send(method, *args, options)
is potentially a breaking change for the underlying method.This PR adds back the condition to pass
{}
if option is empty inform_with
and added a test to make sure it doesn't breakform_with
.Other Information
Thanks to @TooManyBees for help with debug this 🙇♀️