Get rid of the cumbersome fallback_location keyword argument for redirect_back (#40671)

This commit is contained in:
David Heinemeier Hansson 2020-11-24 10:17:11 +01:00 committed by GitHub
parent 75a65a905a
commit 1535af1c31
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 13 deletions

View File

@ -1,3 +1,11 @@
## Unreleased
* Add `redirect_back_or_to(fallback_location, **)` as a more aesthetically pleasing version of `redirect_back_or_to fallback_location:, **`.
The old method name is retained without explicit deprecation.
*DHH*
## Rails 6.1.0.rc1 (November 02, 2020) ##
* Allow `ActionDispatch::HostAuthorization` to exclude specific requests.

View File

@ -64,6 +64,12 @@ module ActionController
self.response_body = "<html><body>You are being <a href=\"#{ERB::Util.unwrapped_html_escape(response.location)}\">redirected</a>.</body></html>"
end
# Soft deprecated alias for <tt>redirect_back_or_to</tt> where the fallback_location location is supplied as a keyword argument instead
# of the first positional argument.
def redirect_back(fallback_location:, allow_other_host: true, **args)
redirect_back_or_to fallback_location, allow_other_host: allow_other_host, **args
end
# Redirects the browser to the page that issued the request (the referrer)
# if possible, otherwise redirects to the provided default fallback
# location.
@ -73,21 +79,20 @@ module ActionController
# subject to browser security settings and user preferences. If the request
# is missing this header, the <tt>fallback_location</tt> will be used.
#
# redirect_back fallback_location: { action: "show", id: 5 }
# redirect_back fallback_location: @post
# redirect_back fallback_location: "http://www.rubyonrails.org"
# redirect_back fallback_location: "/images/screenshot.jpg"
# redirect_back fallback_location: posts_url
# redirect_back fallback_location: proc { edit_post_url(@post) }
# redirect_back fallback_location: '/', allow_other_host: false
# redirect_back_or_to { action: "show", id: 5 }
# redirect_back_or_to @post
# redirect_back_or_to "http://www.rubyonrails.org"
# redirect_back_or_to "/images/screenshot.jpg"
# redirect_back_or_to posts_url
# redirect_back_or_to proc { edit_post_url(@post) }
# redirect_back_or_to '/', allow_other_host: false
#
# ==== Options
# * <tt>:fallback_location</tt> - The default fallback location that will be used on missing +Referer+ header.
# * <tt>:allow_other_host</tt> - Allow or disallow redirection to the host that is different to the current host, defaults to true.
#
# All other options that can be passed to #redirect_to are accepted as
# options and the behavior is identical.
def redirect_back(fallback_location:, allow_other_host: true, **args)
def redirect_back_or_to(fallback_location, allow_other_host: true, **args)
referer = request.headers["Referer"]
redirect_to_referer = referer && (allow_other_host || _url_host_allowed?(referer))
redirect_to redirect_to_referer ? referer : fallback_location, **args

View File

@ -65,19 +65,23 @@ class RedirectController < ActionController::Base
end
def redirect_back_with_status
redirect_back(fallback_location: "/things/stuff", status: 307)
redirect_back_or_to "/things/stuff", status: 307
end
def redirect_back_with_status_and_fallback_location_to_another_host
redirect_back(fallback_location: "http://www.rubyonrails.org/", status: 307)
redirect_back_or_to "http://www.rubyonrails.org/", status: 307
end
def safe_redirect_back_with_status
redirect_back(fallback_location: "/things/stuff", status: 307, allow_other_host: false)
redirect_back_or_to "/things/stuff", status: 307, allow_other_host: false
end
def safe_redirect_back_with_status_and_fallback_location_to_another_host
redirect_back(fallback_location: "http://www.rubyonrails.org/", status: 307, allow_other_host: false)
redirect_back_or_to "http://www.rubyonrails.org/", status: 307, allow_other_host: false
end
def redirect_back_with_explicit_fallback_kwarg
redirect_back(fallback_location: "/things/stuff", status: 307)
end
def host_redirect
@ -326,6 +330,16 @@ class RedirectTest < ActionController::TestCase
assert_equal "http://www.rubyonrails.org/", redirect_to_url
end
def test_redirect_back_with_explicit_fallback_kwarg
referer = "http://www.example.com/coming/from"
@request.env["HTTP_REFERER"] = referer
get :redirect_back_with_explicit_fallback_kwarg
assert_response 307
assert_equal referer, redirect_to_url
end
def test_redirect_to_record
with_routing do |set|
set.draw do