2011-05-09 84 views
1

我期待的模式state/city路径匹配,除非状态变量等于“权威性”Rails 3的路由约束和正则表达式

match '/:state/:city' => 'cities#index', :as => :state_cities, :constraints => {:state => /(?!auth)/ } 

例如,mydomain.com/fl/miami好。 mydomain.com/auth/twitter不好。

我使用的是omniauth,它需要您去/auth/twitter进行身份验证,但是当我输入rake routes时无处可查。

回答

6

基于亩太短的评论,这里就是答案我已经出来:

match '/:state/:city' => 'cities#index', :as => :state_cities, :constraints => OmniauthPassThru.new 

的lib/omniauth_pass_thru.rb

class OmniauthPassThru 
    def initialize 
     @passthru = ["/auth/facebook", "/auth/twitter"] 
    end 

    def matches?(request) 
     return false if @passthru.include?(request.fullpath) 
     true 
    end 
end 
+3

在'matches?'中使用'!request.fullpath.start_with?('/ auth /')'可能会更好一些,不妨保留整个'/ auth'命名空间。 – 2011-05-09 02:15:31

4

你应该能够你的国家/城市路线之前定义/auth路线:

Route priority

并非所有的路线都是一样的。根据config/routes.rb文件中路由的出现顺序,路由具有优先级。优先顺序从上到下。

所以这个顺序应该做正确的事情:

match '/auth/twitter' => ... 
match '/:state/:city' => ... 

您可能想要把你的国家/城市干道自己的命名空间来完全避免问题:

match '/place/:state/:city' => ... 

那将其最高级别清除以供将来使用。

+0

我不能把他们在自己的名称空间,因为这是一个虚荣网址。由于我使用的是运行在Rack中的omniauth gem,因此我也不确定发生了什么。实际上,我的'match:state /:city'已经在路由文件的最后一行。 – Dex 2011-05-09 01:20:39

+1

你可能想更新你的问题,让别人知道你正在使用omniauth。我不知道omniauth在做什么。您是否尝试过使用[constraints对象](http://edgeguides.rubyonrails.org/routing.html#advanced-constraints)来排除'/ auth'? – 2011-05-09 01:47:30

+0

不,我没有使用约束对象,希望内联正则表达式能够做到这一点,但似乎并不是这样。 – Dex 2011-05-09 01:51:07