Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple 'root to' routes in rails 4.0

I am trying to get rails to go to different controller#action according to the subdomain, and this is what I have so far in routes.rb

Petworkslabs::Application.routes.draw do

  get '/', to: 'custom#show', constraints: {subdomain: '/.+/'}, as: 'custom_root'
  get '/',  to: "welcome#home", as: 'default_root'
end

rake shows the correct routes I want it to take

rake routes
      Prefix Verb   URI Pattern             Controller#Action
 custom_root GET    /                       custom#show {:subdomain=>"/.+/"}
default_root GET    /                       welcome#home

But for some reason, I can't get requests like abc.localhost:3000 to hit the custom controller. It always routes it to welcome#home. Any ideas? I am fairly new to rails, so any tips about general debugging would also be appreciated.

EDIT: I stepped through the code using the debugger and this is what I found

(rdb:32) request.domain "abc.localhost" (rdb:32) request.subdomain "" (rdb:32) request.subdomain.present? false

Looks like for some reason rails thinks that the subdomain is not present, even though its there. I wonder if its because I am doing this localhost.

like image 701
Mahesh Guruswamy Avatar asked Oct 04 '13 00:10

Mahesh Guruswamy


3 Answers

Updated Answer:

Worked for me on Rails 3 & 4:

get '/' => 'custom#show', :constraints => { :subdomain => /.+/ }
root :to => "welcome#home"
like image 143
manishie Avatar answered Sep 22 '22 02:09

manishie


@manishie's answer is right, but you'll still likely have issues in your devo environment if you're using localhost. To fix it add the following line to config/environments/development.rb:

config.action_dispatch.tld_length = 0

and then use @manishie's answer in routes.rb:

get '/' => 'custom#show', :constraints => { :subdomain => /.+/ }
root :to => "welcome#home"

The issue is that tld_length defaults to 1 and there's no domain extension when you're using localhost so rails fails to pickup the subdomain. pixeltrix explains it really well here: https://github.com/rails/rails/issues/12438

like image 45
Ryan Epp Avatar answered Sep 22 '22 02:09

Ryan Epp


For some reason request.subdomain was not getting populated at all (I suspect this is because I have doing this on localhost, I have opened a bug here https://github.com/rails/rails/issues/12438). This was causing the regex match in routes.rb to fail. I ended up creating a custom matches? method for Subdomain which looks something like this

class Subdomain
  def self.matches?(request)

    request.domain.split('.').size>1 && request.subdomain != "www"
  end
end

and hooking that up in routes.rb

constraints(Subdomain) do
  get '/',  to: "custom#home", as: 'custom_root'
end

this seems to work.

EDIT: More information in the github issues page https://github.com/rails/rails/issues/12438

like image 29
Mahesh Guruswamy Avatar answered Sep 20 '22 02:09

Mahesh Guruswamy