Handling Multiple Domains Routes in your Ruby on Rails Applications

In this post I’ll share with you a technique to make your Ruby on Rails applications handle multiple domains using routes constraints.

Because your development environment will use a different domain than your production environment, you should somewhere configure which domains will be use in each environment. You can configure this in your application settings file.

# config/settings.yml

development:
  firstapp_domain: firstapp.dev
  secondapp_domain: secondapp.dev

production:
  firstapp_domain: firstapp.com
  secondapp_domain: secondapp.com

The .dev TLD denotes I am using Pow, a Rack Server for Mac OS.

Next, create a domain constraint resolver which will return whether an HTTP request domain matches or not a domain of your application.

#lib/constraints/domain_constraint.rb

class Constraints::DomainConstraint

  def initialize(domain)
    @domain = [domain].flatten
  end

  def matches?(request)
    @domain.include? request.domain
  end
end

The next and most important step is to enclose your routes within your domain constraints.

# config/routes.rb:

DomainsConstraintsExample::Application.routes.draw do

  constraints DomainConstraint.new(Rails.application.settings[:firstapp_domain]) do
    resources :firstapp
  end

  constraints DomainConstraint.new(Rails.application.settings[:secondapp_domain]) do
    resources :secondapp
  end
end

With the above routes, a request to firstapp.com/firstapp will be handled by the firstapp controller and a request to secondapp.com/secondapp will be handled by the secondapp controller.

I suggest you to create ruby namespaces for each of your domains so as group controllers of the same domains.

.
`-- app
    `-- controllers
        |-- secondapp
        |   `-- secondapp_controller.rb
        `-- firstapp
            `-- firstapp_controller.rb

You will need to rename your routes so as to specify the namespace of each controller:

DomainsConstraintsExample::Application.routes.draw do

  constraints DomainConstraint.new(Rails.application.settings[:firstapp_domain]) do
    resources :firstapp, controller: "firstapp/firstapp"
  end

  constraints DomainConstraint.new(Rails.application.settings[:secondapp_domain]) do
    resources :secondapp, controller: "secondapp/secondapp"
  end
end

Last but not least, remember that you should configure your web server virtual hosts file to handle this domains. In Nginx it will be something like this:

server {
  server_name firstapp.com secondapp.com
}

Hope you found it useful and see you in the next post.

ruby

Comments

comments powered by Disqus