36

I want to redirect all root requests to a /pages/home url, but I want to keep all the params used in the original request.

So:

http://myserver.com/?param1=value1&param2=value2

Becomes

http://myserver.com/pages/home?param1=value1&param2=value2

There are several SO questions about passing params in a redirect but I haven't found any related to passing request's params.

fguillen
  • 36,125
  • 23
  • 149
  • 210

4 Answers4

42
# routes.rb
root :to => redirect { |params, request| "/pages/home?#{request.params.to_query}" }

Update 1

You can also play with the request.params to build the new path:

root :to => redirect { |params, request| "/pages/#{request.params[:page]}.html?#{request.params.to_query}" }
fguillen
  • 36,125
  • 23
  • 149
  • 210
  • I'm posting my own solution because when I try to find a solution in SO I didn't find it. So I hope it is helpful for the next one coming with the same doubt – fguillen Jun 05 '13 at 14:56
  • Another addendum to redirect regardless of format/content-type (in Rails 3.2.2): `match '/*page', to: redirect {|params,request| "/pages/#{params[:page]}.#{request.format.to_sym.to_s}?#{request.params.to_query}"}` – spyle Aug 06 '15 at 15:40
  • The dangling question mark can be dealt with: `root :to => redirect { |_, request| ["/pages/#{request.params[:page]}.html", request.params.to_query].reject(&:blank?).join("?") }` – Epigene Sep 30 '15 at 13:16
  • Upon investigation it has come to my attention that this is actually unnecessary (at least as of Rails 4.1), it appears to me that redirect() natively does exactly this if you do NOT pass it any params. (If you do pass it a URL that contains ? it appears to me to prefer those rather than the ones from the request). This makes the original answer here less valid, since it is unneeded code. What is shown in "Update 1" does indeed allow you to munge the redirect path as explained. – Jason FB Jan 26 '16 at 13:13
  • 1
    Also on Rails4 it seems like this function does not work (with params included in redirect rule this way) – Gediminas Šukys Feb 22 '16 at 11:27
42

The other answer works but leaves a ? at the end in case there are no parameters.

This seems to do the trick without the side effects:

root to: redirect(path: '/quick_searches/new')

Hope it helps!

fguillen
  • 36,125
  • 23
  • 149
  • 210
Kaukas
  • 431
  • 4
  • 2
  • The only _con_ with this solution is that you can't play around with the `request` to build the new `path` as I show in the _Update 1_ of my answer. – fguillen Mar 24 '15 at 09:14
  • 1
    although @fguillen is correct about that, this is actually the more accurate answer because the original question asked only about passing params (like UTMs) while a redirection happens. It did not ask about a dynamic destination based on those params (if it had @ fguillen's answer in "Update 1" would be more accurate). In fact, this answer reveals the flaw in the question, which is that at least in Rails 4.1 (I tested), this is automatic. – Jason FB Jan 26 '16 at 13:16
21

In Rails 5, this can be now be done concisely simply by rewriting ONLY the path component in the redirect (so all original query params will be retained):

# in routes.rb
root to: redirect(path: '/pages/home')

Relevant documentation link:

http://api.rubyonrails.org/classes/ActionDispatch/Routing/Redirection.html

Francis Li
  • 482
  • 7
  • 12
1

Building on @fguillen's answer for Rails4

You need two lines in routes.rb

# in routes.rb
match "/pages/home", to: 'pages#index', via: :get    
match "/", to: redirect{ |params, request| [ "/pages/home", request.env["rack.request.query_string"] ].join("?") }, via: :all

The join on an array also handles the dangling question mark at the end in case there are no parameters.

Epigene
  • 3,634
  • 1
  • 26
  • 31