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.
Updated Answer:
Worked for me on Rails 3 & 4:
get '/' => 'custom#show', :constraints => { :subdomain => /.+/ }
root :to => "welcome#home"
@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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With