Использование отрицательного взгляда, как предложено edgerunner & George, замечательно.
В основном шаблон будет выглядеть так:
constrain :subdomain => /^(?!signup\Z|api\Z)(\w+)/ do
resources :whatever
end
Это то же самое, что предложение Джорджа, но я изменил\b
до \Z
- переход от границы слова к концу самой входной строки (как отмечено в моем комментарии к ответу Джорджа).
Вот несколько тестов, показывающих разницу:
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