Homar
Homar

Reputation: 1519

Rails: Routing subdomain to a resource

Is it possible to map a subdomain to a resource? I have a company model. Currently, using subdomain_fu, my routing file contains:

map.company_root  '', :controller => 'companies', :action => 'show',
                      :conditions => { :subdomain => /.+/ }

My Company model contains a "subdomain" column.

Whilst this works as intended, it's a named route and isn't restful. Essentially, I need to map "name.domain.com" to the show action for the companies controller. Is a named route the way to go, or can I use a resource route?

Upvotes: 8

Views: 9046

Answers (4)

William Denniss
William Denniss

Reputation: 16336

Using the resource linked from Daniel's answer, in Rails 3 the way to route '/' to a different controller depending on the subdomain is as follows:

match '/' => 'somecontroller#action', :constraints => { :subdomain => 'yoursubdomain' }

Upvotes: 2

Daniel Kehoe
Daniel Kehoe

Reputation: 10952

Here's a complete example implementation of Rails 3 subdomains with authentication (along with a detailed tutorial). It's much easier to do this in Rails 3 than in Rails 2 (no plugin required).

Upvotes: 2

Steve Graham
Steve Graham

Reputation: 3021

One can pass conditions to a resource route as well as a named route. In an application I am involved with everything is scoped to an account. A :before_filter loads the account using the subdomain. Thus for resources scoped to an account, we want to scope the routes to urls with subdomains. The DRY way to do this is to use map with options:

  map.with_options :conditions => {:subdomain => /.+/} do |site|
    site.resources :user_sessions, :only => [:new, :create, :destroy]
    site.resources :users
    site.login 'login', :controller => "user_sessions", :action => "new"
    site.logout 'logout', :controller => "user_sessions", :action => "destroy"
    …
  end

  map.connect 'accounts/new/:plan', :controller => "accounts", :action => "new"
  map.resources :accounts, :only => [:new, :create]

As you can see a named route will accept a conditions hash with a subdomain too. You can also adopt the approach Ryan illustrated above or you can specify conditions on a per resource basis:

  map.resources :users, :conditions => {:subdomain => /.+/}

Upvotes: 8

ryanb
ryanb

Reputation: 16287

I don't know of a way to do this with map.resources. It does accept a :conditions option but I'm not sure how to remove the /companies/ portion of the URL. However, map.resources is primarily a convenient way to generate a bunch of named routes, which you can do manually. Something like this.

map.company '', :controller => 'companies', :action => 'show', :conditions => { :subdomain => /.+/, :method => :get }
map.new_company 'new', :controller => 'companies', :action => 'new', :conditions => { :subdomain => /.+/, :method => :get }
map.edit_company 'edit', :controller => 'companies', :action => 'edit', :conditions => { :subdomain => /.+/, :method => :get }
map.connect '', :controller => 'companies', :action => 'create', :conditions => { :subdomain => /.+/, :method => :post }
map.connect '', :controller => 'companies', :action => 'update', :conditions => { :subdomain => /.+/, :method => :put }
map.connect '', :controller => 'companies', :action => 'destroy', :conditions => { :subdomain => /.+/, :method => :delete }

Untested, but it should get you close.

Upvotes: 4

Related Questions