I had a functioning redirect in my routes.rb like so;
match "/invoices" => redirect("/dashboard")
I now want to add a query string to this so that, e.g.,
/invoices?show=overdue
will be redirected to
/dashboard?show=overdue
I've tried several things. The closest I have got is;
match "/invoices?:string" => redirect("/dashboard?%{string}")
which gives me the correct output but with the original URL still displayed in the browser.
I'm sure I'm missing something pretty simple, but I can't see what.
You can use request object in this case:
match "/invoices" => redirect{ |p, request| "/dashboard?#{request.query_string}" }
The simplest way to do this (at least in Rails 4) is do use the options mode for the redirect call..
get '/invoices' => redirect(path: '/dashboard')
This will ONLY change the path component and leave the query parameters alone.
While the accepted answer works perfectly, it is not quite suitable for keeping things DRY — there is a lot of duplicate code once you need to redirect more than one route.
In this case, a custom redirector is an elegant approach:
class QueryRedirector
def call(params, request)
uri = URI.parse(request.original_url)
if uri.query
"#{@destination}?#{uri.query}"
else
@destination
end
end
def initialize(destination)
@destination = destination
end
end
Now you can provide the redirect
method with a new instance of this class:
get "/invoices", to: redirect(QueryRedirector.new("/dashboard"))
I have a written an article with a more detailed explanation.