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 subdo开发者_Go百科main. 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
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
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
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
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
精彩评论