Jonniesweb
Jonniesweb

Reputation: 15

Rails routes redirect for both a single and wildcard path

In my Rails app's config/routes.rb I’m trying to redirect any url that is or starts with /support to /contact. So a user going to /support/a/b would redirect to /contact/a/b and going to /support would redirect to /contact.

So far this is possible with two routes like the following:

get '/support*all' => redirect(path: '/contact%{all}')
get '/support' => redirect(path: '/contact')

My question is, is it possible to have one route that behaves like the above two routes?

Upvotes: 0

Views: 1096

Answers (1)

7stud
7stud

Reputation: 48599

Parenthesis are used to make a segment optional:

get '/support(/*all') => redirect(path: '/contact/%{all}')

But redirect() will produce an error if all matches nothing, i.e. when the path is /support. In that case, the redirect path will be literally '/contact/%{all}'--no substitution is done. So you need to provide a default value for all (note that defaults: is an argument for the get() method):

get '/support(/*all)', to: redirect(path: "/contact/%{all}"), defaults: {all: ''}

You can also provide a block for the redirect() method, and the return value of the block will be used as the redirect path:

get '/support(/*all)', to: redirect {|path_params, req|  #Cannot use do-end to delimit this block.
  "/contact/#{path_params[:all]}"
}

The thing to note about the block solution is that when all doesn't end up matching anything in the path, then there will be no entry for all in the params Hash, therefore path_params[:all] will return nil. Subsequently, when you interpolate nil into a String, nil.to_s is called, which returns a blank string.

Upvotes: 10

Related Questions