George Drummond
George Drummond

Reputation: 91

Subdomain constraint and excluding certain subdomains

In my routes.rb file I want to use the subdomain constraints feature in rails3 however I would like to exclude certain domains from the catch all route. I dont want to have certain controller in a specific subdomain. What would be the best practice in doing so.

# this subdomain i dont want all of the catch all routes
constraints :subdomain => "signup" do
  resources :users
end

# here I want to catch all but exclude the "signup" subdomain
constraints :subdomain => /.+/ do
  resources :cars
  resources :stations
end

Upvotes: 6

Views: 4909

Answers (4)

edgerunner
edgerunner

Reputation: 14973

Revisiting this old question, I just thought of another approach that could work depending on what you want…

The Rails Router tries to match a request to a route in the order specified. If a match is found, the remaining routes are not checked. In your reserved subdomain block, you could glob up all remaining routes and send the request to an error page.

constraints :subdomain => "signup" do
  resources :users
  # if anything else comes through the signup subdomain, the line below catches it
  route "/*glob", :to => "errors#404" 
end

# these are not checked at all if the subdomain is 'signup'
resources :cars
resources :stations

Upvotes: 2

Alan H.
Alan H.

Reputation: 16588

Using a negative lookahead as suggested by edgerunner & George is great.

Basically the pattern is going to be:

constrain :subdomain => /^(?!signup\Z|api\Z)(\w+)/ do
  resources :whatever
end

This is the same as George's suggestion but I changed the \b to \Z — changing from a word boundary to the end of the input string itself (as noted in my comment on George's answer).

Here are a bunch of test cases showing the difference:

irb(main):001:0> re = /^(?!www\b)(\w+)/
=> /^(?!www\b)(\w+)/
irb(main):003:0> re =~ "www"
=> nil
irb(main):004:0> re =~ "wwwi"
=> 0
irb(main):005:0> re =~ "iwwwi"
=> 0
irb(main):006:0> re =~ "ww-i"
=> 0
irb(main):007:0> re =~ "www-x"
=> nil
irb(main):009:0> re2 = /^(?!www\Z)(\w+)/
=> /^(?!www\Z)(\w+)/
irb(main):010:0> re2 =~ "www"
=> nil
irb(main):011:0> re2 =~ "wwwi"
=> 0
irb(main):012:0> re2 =~ "ww"
=> 0
irb(main):013:0> re2 =~ "www-x"
=> 0

Upvotes: 1

George Drummond
George Drummond

Reputation: 91

this is the solution I came to.

constrain :subdomain => /^(?!signup\b|api\b)(\w+)/ do
  resources :whatever
end

it will match api but not apis

Upvotes: 3

edgerunner
edgerunner

Reputation: 14973

You can use negative lookahead in your constraint regex to exclude some domains.

constrain :subdomain => /^(?!login|signup)(\w+)/ do
  resources :whatever
end

Try this out on Rubular

Upvotes: 11

Related Questions