diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index 92e94ee463f398884e4a0e2bdb9bf5a4a2e5b00e..86e98c011c2f8274edd1da05ce21b933aeca4a37 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,3 +1,8 @@ +* Fix URL generation with `:trailing_slash` such that it does not add + a trailing slash after `.:format` + + *Dan Langevin* + * Build full URI as string when processing path in integration tests for performance reasons. @@ -131,4 +136,5 @@ *Tony Wooster* + Please check [4-1-stable](https://github.com/rails/rails/blob/4-1-stable/actionpack/CHANGELOG.md) for previous changes. diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index a6c17f50a58311eb07c7f8659ae6edc3988f42bc..4cba4f5f37e64bda08bdfe3093677e1d71d39f53 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -37,13 +37,7 @@ def url_for(options) path = options[:script_name].to_s.chomp("/") path << options[:path].to_s - if options[:trailing_slash] - if path.include?('?') - path.sub!(/\?/, '/\&') - else - path.sub!(/[^\/]\z|\A\z/, '\&/') - end - end + add_trailing_slash(path) if options[:trailing_slash] result = path @@ -66,6 +60,18 @@ def url_for(options) private + def add_trailing_slash(path) + # includes querysting + if path.include?('?') + path.sub!(/\?/, '/\&') + # does not have a .format + elsif !path.include?(".") + path.sub!(/[^\/]\z|\A\z/, '\&/') + end + + path + end + def build_host_url(options) if match = options[:host].match(HOST_REGEXP) options[:protocol] ||= match[1] unless options[:protocol] == false diff --git a/actionpack/test/dispatch/url_generation_test.rb b/actionpack/test/dispatch/url_generation_test.rb index 910ff8a80fdb35771f2fc9b1da00323c2653c3c8..a4dfd0a63dd4fb2168041c8fc88c35f173969e95 100644 --- a/actionpack/test/dispatch/url_generation_test.rb +++ b/actionpack/test/dispatch/url_generation_test.rb @@ -15,6 +15,8 @@ def index Routes.draw do get "/foo", :to => "my_route_generating#index", :as => :foo + resources :bars + mount MyRouteGeneratingController.action(:index), at: '/bar' end @@ -109,6 +111,22 @@ def app test "omit subdomain when key is blank" do assert_equal "http://example.com/foo", foo_url(subdomain: "") end + + test "generating URLs with trailing slashes" do + assert_equal "/bars.json", bars_path( + trailing_slash: true, + format: 'json' + ) + end + + test "generating URLS with querystring and trailing slashes" do + assert_equal "/bars.json?a=b", bars_path( + trailing_slash: true, + a: 'b', + format: 'json' + ) + end + end end