Skip to content

Commit 581aac7

Browse files
authored
Merge pull request rails#43287 from Shopify/append-slash
Append trailing slash when the path is generated
2 parents 536ca71 + f593e97 commit 581aac7

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)