Last Updated: December 19, 2019
·
6.417K
· dommmel

redirect to canonical host in Rails 4

Sometimes you want to use a single host name for your app and have requests for other host names redirected to the canonical host.

Example:
myfancyapp.herokuapp.com/* should redirect to myfancyapp.com/*`

You could use rack middleware gem like rack-canonical-host or rack-rewrite.

You can also achieve the same result without any additional gem by using contraints in Rails's routes.

in config/routes.rb

if Rails.env.production?
  constraints(:host => /^(?!myfancyapp\.com)/i) do
    match "/(*path)" => redirect {
      |params, req| "http://myfancyapp.com/#{params[:path]}"
      },  via: [:get, :post]
  end
end

If you – like me – prefer keeping your settings in env variables you can use something along these lines

if ENV['CANONICAL_HOST']
    constraints(:host => Regexp.new("^(?!#{Regexp.escape(ENV['CANONICAL_HOST'])})")) do
      match "/(*path)" => redirect { |params, req| "http://#{ENV['CANONICAL_HOST']}/#{params[:path]}" },  via: [:get, :post]
    end
  end

3 Responses
Add your response

Hello, this is my code (similar to yours but its non www/ or non www.domain.sk to that domain) :

constraints(:host => /^(?!www.domain\.sk)/i) do
match "/(*path)" => redirect { |params, req| "http://www.domain.sk/#{params[:path]}" }, via: :all

I run the app on heroku and have all other domains with and without subdomain pointed to www.domain.sk with CNAME DNS. When I type any domain combination it redirects me properly to www.domain.sk, but the application shows error. Dont you know where might be the problem? Is it heroku or rails specific error?

over 1 year ago ·

not need to help, the mistake was I wrapped with this constraint "rule" all routes, when I included this only to begining of file everything worked fine.

over 1 year ago ·

Maybe is some gem I'm using, but after using this, my confirmation mail (which comes in the link like: /users/confirmation?confirmation_token=XXXXXXX ) stops working. It redirects to /users/confirmation instead, on the new domain.

over 1 year ago ·