Joris Van Hecke
Joris Van Hecke

Reputation: 41

Subdomain based resources in Rails

I am looking for a simple way to replace all my routes matching mydomain.com/resources/xx by xx.mydomain.com with Rails 4.

Would anyone have an idea to do that easily and that would work with nested resources as well?

Thanks, Joris

Upvotes: 4

Views: 966

Answers (2)

Richard Peck
Richard Peck

Reputation: 76774

Constraints

What you're looking for is constraints in your routes, specifically that you're looking to use one to determine whether you have a subdomain that you can access

There are a number of resources on how to achieve this:

The bottom line is that you'll probably have to create a custom subdomai constraint, which you can then use the standard routing structure for:

#lib/subdomain.rb
class Subdomain
  def self.matches?(request)
    if request.subdomain.present? && request.subdomain != 'www'
        account = Account.find_by username: request.subdomain
        return true if account # -> if account is not found, return false (IE no route)
    end
  end
end


#config/routes.rb
constraints(Subdomain) do
   get "/", to: "controller#action"
   resources :posts #-> subdomain.domain.com/posts
   ...
end

The above is untested - I also found the following with Rails' documentation:

#lib/subdomain.rb
class Subdomain
  def initialize
    @accounts = Account.all
  end

  def matches?(request)
    if request.subdomain.present? && request.subdomain != 'www'
        @accounts.include?(request.subdomain)
    end
  end
end

#config/routes.rb
constraints: Subdomain.new do
   get "/", to: "controller#action"
   resources :posts #-> subdomain.domain.com/posts
   ...
end

Upvotes: 2

Carlos Cervantes
Carlos Cervantes

Reputation: 1447

Here how I have done it before in a Rails 3 app:

  constraints :subdomain => /ambassador/ do
    namespace(:influencer, :path => '/') do
      root :to => 'home#index'
      match 'home' => 'sweepstakes#index', :as => :influencer_home
      resources :sweepstakes
      resources :associates
      resources :widgets
      resources :sessions
      resources :reports do
        resource :member
      end
      match 'faq' => 'info#faq'
    end
  end

Be sure to put this block towards the top of the routes.rb file so it takes precedence.

You can of course nest your resources in here like normal.

Upvotes: 0

Related Questions