Reputation: 726
I have a problem, recently the name of a controller changed.
I changed the routes file to accept calls using the old controller name, for people with bookmarks referencing the old name:
get '/old/about', to: redirect('/new/about')
get '/old/report/:client', to: redirect('/new/report/%{client}')
get '/old/:sub_path', to: redirect('/new/%{sub_path}')
that works fine. But for calls with query string it blocks it to /report/200. for example:
/old/report/200?c_id=257&end=2013-10-19&num_results=294540&start=2013-10-13
it cuts the url to:
old/report/200
and shows me an error because of the lack of parameters. Do you know what can I do? (I thought the :sub_path line in the routes would help but not) :(
Upvotes: 13
Views: 5284
Reputation: 1943
The existing answers work perfectly, but are 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 "/old/report/:client", to: redirect(QueryRedirector.new("/new/report/#{params[:client]}"))
I have a written an article with a more detailed explanation.
Upvotes: 0
Reputation: 10063
Modify redirect
to use the path:
option to preserve the querystring:
- get '/old/about', to: redirect('/new/about')
+ get '/old/about', to: redirect(path: '/new/about')
This is demonstrated in the API docs for redirect
, see http://api.rubyonrails.org/classes/ActionDispatch/Routing/Redirection.html#method-i-redirect
Upvotes: 21
Reputation: 1462
Building on Alejandra's answer, more verbose but without the ?
if there's no query string:
get "/old/report/:client", to: redirect{ |params, request| ["/new/report/#{params[:client]}", request.query_string.presence].compact.join('?') }
So /old/report/:client?with=param
will become /new/report/:client?with=param
,
and /old/report/:client
will become /new/report/:client
.
Upvotes: 3
Reputation: 726
The question mention by Matt helped me to figure out my answer (thanks a lot!). It was a slightly different for my specific case. Im leaving the answer that worked for me for future reference.
match "/old/report/:client" => redirect{ |params, request| "/new/report/#{params[:client]}?#{request.query_string}" }
Upvotes: 12