views:

1748

answers:

3

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?

+4  A: 

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.

ryanb
Thanks Ryan! What I've done is place the companies resource under a namespace. This allows access to the new, edit, create, update and destroy actions without a subdomain: I.e. domain.com/namespace/companies/actionThen, outside the namespace, I'm using that map.company named route (when a subdomain is present). Everything seems to be mapping nicely.
Homar
+3  A: 

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 => /.+/}
Steve Graham
+1  A: 

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).

Fortuity