There are multiple ways to redirect URLs to a different URL in Rails, and they differ in small but important nuances.
Imagine you want to redirect the following url https://www.example.com/old_location?foo=bar
to https://www.example.com/new_location?foo=bar
.
Variant A
You can use ActionController::Redirecting#redirect_to
in a controller action
class SomeController < ActionController::Base
def old_location
redirect_to(new_location_url(params.permit(:foo)))
end
end
This will:
- It will redirect with a 302 status code
- It will raise
ActionController::UnfilteredParameters
if there is any other query param thanfoo
, e.g.https://www.example.com/old_location?another_param=1
. This is becauseurl_for
will callto_h
onActionController::Parameters
, which will raise if there are unpermitted parameters.
Variant B
You can also use ActionDispatch::Routing::Redirection#redirect
in the routes.rb
file:
get 'old_location', redirect(path: '/new_location')
This will:
- Redirect with a 301 status code
- It will forward all query parameters to the redirect url. E.g.
https://example.com/old_location?b=b
will redirect tohttps://example.com/new_location?b=b
.
You can achieve the same forwarding of query parameters with variant A as explained here, but please be aware of its security implications.
Both variants have options to change their default behaviour.
Search engines and redirects
If you have a public facing website that ranks on search engines, choosing the correct redirect code is important. If you decide to change your url structure and want the search engines to index the new target url (/new_location?foo=bar
) then you should use a 301. You can more about how google handles this
here
Show archive.org snapshot
.