Skip to content

Commit f593e97

Browse files
committed
Append trailing slash when the path is generated
Instead of trying to parse the path later to insert the slash or bail out if the path look like it has a format indicator. This patch is based on the assumption that `url_for(path: '/blah')` is not an actual public API.
1 parent e44ce53 commit f593e97

File tree

4 files changed

+47
-12
lines changed

4 files changed

+47
-12
lines changed

actionpack/lib/action_dispatch/http/url.rb

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ def path_for(options)
7171
path = options[:script_name].to_s.chomp("/")
7272
path << options[:path] if options.key?(:path)
7373

74-
add_trailing_slash(path) if options[:trailing_slash]
74+
path = "/" if options[:trailing_slash] && path.blank?
75+
7576
add_params(path, options[:params]) if options.key?(:params)
7677
add_anchor(path, options[:anchor]) if options.key?(:anchor)
7778

@@ -101,14 +102,6 @@ def extract_subdomains_from(host, tld_length)
101102
parts[0..-(tld_length + 2)]
102103
end
103104

104-
def add_trailing_slash(path)
105-
if path.include?("?")
106-
path.sub!(/\?/, '/\&')
107-
elsif !path.include?(".")
108-
path.sub!(/[^\/]\z|\A\z/, '\&/')
109-
end
110-
end
111-
112105
def build_host_url(host, port, protocol, options, path)
113106
if match = host.match(HOST_REGEXP)
114107
protocol ||= match[1] unless protocol == false

actionpack/lib/action_dispatch/routing/route_set.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,11 @@ def url_for(options, route_name = nil, url_strategy = UNKNOWN, method_name = nil
820820

821821
route_with_params = generate(route_name, path_options, recall)
822822
path = route_with_params.path(method_name)
823+
824+
if options[:trailing_slash] && !options[:format] && !path.end_with?("/")
825+
path += "/"
826+
end
827+
823828
params = route_with_params.params
824829

825830
if options.key? :params

actionpack/test/dispatch/request_test.rb

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,6 @@ class RequestUrlFor < BaseRequestTest
4242

4343
assert_equal "/books", url_for(only_path: true, path: "/books")
4444

45-
assert_equal "http://www.example.com/books/?q=code", url_for(trailing_slash: true, path: "/books?q=code")
46-
assert_equal "http://www.example.com/books/?spareslashes=////", url_for(trailing_slash: true, path: "/books?spareslashes=////")
47-
4845
assert_equal "http://www.example.com", url_for
4946
assert_equal "http://api.example.com", url_for(subdomain: "api")
5047
assert_equal "http://example.com", url_for(subdomain: false)

actionpack/test/dispatch/url_generation_test.rb

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,16 @@ class ::MyRouteGeneratingController < ActionController::Base
1212
def index
1313
render plain: foo_path
1414
end
15+
16+
def add_trailing_slash
17+
render plain: url_for(trailing_slash: true, params: request.query_parameters, format: params[:format])
18+
end
1519
end
1620

1721
Routes.draw do
1822
get "/foo", to: "my_route_generating#index", as: :foo
1923
get "(/optional/:optional_id)/baz", to: "my_route_generating#index", as: :baz
24+
get "/add_trailing_slash", to: "my_route_generating#add_trailing_slash", as: :add_trailing_slash
2025

2126
resources :bars
2227

@@ -156,7 +161,42 @@ def app
156161
assert_equal "http://www.example.com/baz", baz_url("")
157162
end
158163

164+
test "generating the current URL with a trailing slashes" do
165+
get "/add_trailing_slash"
166+
assert_equal "http://www.example.com/add_trailing_slash/", response.body
167+
end
168+
169+
test "generating the current URL with a trailing slashes and query string" do
170+
get "/add_trailing_slash?a=b"
171+
assert_equal "http://www.example.com/add_trailing_slash/?a=b", response.body
172+
end
173+
174+
test "generating the current URL with a trailing slashes and format indicator" do
175+
get "/add_trailing_slash.json"
176+
assert_equal "http://www.example.com/add_trailing_slash.json", response.body
177+
end
178+
159179
test "generating URLs with trailing slashes" do
180+
assert_equal "/bars/", bars_path(
181+
trailing_slash: true,
182+
)
183+
end
184+
185+
test "generating URLs with trailing slashes and dot including param" do
186+
assert_equal "/bars/hax0r.json/", bar_path(
187+
"hax0r.json",
188+
trailing_slash: true,
189+
)
190+
end
191+
192+
test "generating URLs with trailing slashes and query string" do
193+
assert_equal "/bars/?a=b", bars_path(
194+
trailing_slash: true,
195+
a: "b"
196+
)
197+
end
198+
199+
test "generating URLs with trailing slashes and format" do
160200
assert_equal "/bars.json", bars_path(
161201
trailing_slash: true,
162202
format: "json"

0 commit comments

Comments
 (0)