1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

url_for does not modify polymorphic options

The `url_for` methods in `actionpack` and `actionview`
now make a copy of the provided options
before generating polymorphic paths or URLs.

The bug in the previous behavior
is most noticeable in a case like:

    url_options = [:new, :post, param: 'value']

    if current_page?(url_options)
      css_class = "active"
    end

    link_to "New Post", url_options, class: css_class
This commit is contained in:
Bernerd Schaefer 2015-09-04 12:23:29 -07:00
parent 451b954c2f
commit ee63532d40
6 changed files with 47 additions and 3 deletions

View file

@ -1,3 +1,7 @@
* `url_for` does not modify its arguments when generating polymorphic URLs.
*Bernerd Schaefer*
* Update `ActionController::TestSession#fetch` to behave more like
`ActionDispatch::Request::Session#fetch` when using non-string keys.

View file

@ -180,7 +180,8 @@ module ActionDispatch
when Symbol
HelperMethodBuilder.url.handle_string_call self, options
when Array
polymorphic_url(options, options.extract_options!)
components = options.dup
polymorphic_url(components, components.extract_options!)
when Class
HelperMethodBuilder.url.handle_class_call self, options
else

View file

@ -451,6 +451,26 @@ module AbstractController
end
end
def test_url_for_with_array_is_unmodified
with_routing do |set|
set.draw do
namespace :admin do
resources :posts
end
end
kls = Class.new { include set.url_helpers }
kls.default_url_options[:host] = 'www.basecamphq.com'
original_components = [:new, :admin, :post, { param: 'value' }]
components = original_components.dup
kls.new.url_for(components)
assert_equal(original_components, components)
end
end
private
def extract_params(url)
url.split('?', 2).last.split('&').sort

View file

@ -1,3 +1,7 @@
* `url_for` does not modify its arguments when generating polymorphic URLs.
*Bernerd Schaefer*
* `number_to_currency` and `number_with_delimiter` now accept custom `delimiter_pattern` option
to handle placement of delimiter, to support currency formats like INR

View file

@ -105,10 +105,11 @@ module ActionView
when :back
_back_url
when Array
components = options.dup
if _generate_paths_by_default
polymorphic_path(options, options.extract_options!)
polymorphic_path(components, components.extract_options!)
else
polymorphic_url(options, options.extract_options!)
polymorphic_url(components, components.extract_options!)
end
else
method = _generate_paths_by_default ? :path : :url

View file

@ -785,6 +785,13 @@ class SessionsController < ActionController::Base
@session = Session.new(params[:id])
render inline: "<%= url_for([@workshop, @session]) %>\n<%= link_to('Session', [@workshop, @session]) %>"
end
def edit
@workshop = Workshop.new(params[:workshop_id])
@session = Session.new(params[:id])
@url = [@workshop, @session, format: params[:format]]
render inline: "<%= url_for(@url) %>\n<%= link_to('Session', @url) %>"
end
end
class PolymorphicControllerTest < ActionController::TestCase
@ -815,4 +822,11 @@ class PolymorphicControllerTest < ActionController::TestCase
get :show, params: { workshop_id: 1, id: 1 }
assert_equal %{/workshops/1/sessions/1\n<a href="/workshops/1/sessions/1">Session</a>}, @response.body
end
def test_existing_nested_resource_with_params
@controller = SessionsController.new
get :edit, params: { workshop_id: 1, id: 1, format: "json" }
assert_equal %{/workshops/1/sessions/1.json\n<a href="/workshops/1/sessions/1.json">Session</a>}, @response.body
end
end