Rails REST路由:资源项ID中的点

我在我的routes.rb中有以下内容:

resources :users, :except => [:new, :create] do get 'friends', :as => :friends, :on => :member, :to => "users#friends" end 

并在我的user.rb中关注:

 def to_param self.login end 

例如,当登录点上的用户(例如’any.thing’)来自facebook时,rails会发出路由错误(找不到路由,我想这是因为它识别了点之后作为格式或路由约束的任何内容)。 我怎么能克服这个错误?

您可以用其他字符替换句点:

 def to_param login.gsub(/\./,"-") # note: 'self' is not needed here end user = User.find_by_login("bart.simpson") user_path(user) # => "/users/bart-simpson" 

编辑

你是对的,这无法处理映射到相同值的唯一登录。 也许更好的方法是在路线中使用分段约束:

  match 'users/(:id)' => 'users#show', :constraints => { :id => /[0-9A-Za-z\-\.]+/ } 

这应该允许"/users/bart-simpson"/users/bart.simpson"分别生成:id => "bart-simpson":id => "bart.simpson" 。你必须改变正则表达式添加URL的所有可接受的字符。

请注意,这在Rails路由指南的 3.2节中提到:

默认情况下,动态段不接受点 – 这是因为点用作格式化路径的分隔符。 如果您需要在动态段中使用点,请添加一个覆盖它的约束 – 例如:id => /[^\/]+/允许除斜杠之外的任何内容。

以下约束定义允许id中的点以及除斜杠之外的任何字符。

必须明确定义支持的格式(此处为.html和.json),以便不被id占用。

 resources :foobars, :constraints => { :id => /[^\/]+(?=\.html\z|\.json\z)|[^\/]+/ } 

该约束定义适用于Rails 3.1

对于早期的Rails版本,您可能需要在regin gem中支持前瞻性支持(它以机架式gem出售)

允许:id段包含除'/'之外'/'任何字符:

 match 'users/(:id)' => 'users#show', :constraints => {:id => /[^\/]+/} 

它写在其中一个答案的其他地方,但这是IMO最简单的方法。