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

时间:2011-03-07 17:13:56

标签: ruby-on-rails ruby-on-rails-3 rest url-routing

我的路线中有以下内容.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会发出路由错误(找不到路由,我想这是因为它将点后面的任何内容识别为格式或因为路线约束)。我怎么能克服这个错误?

3 个答案:

答案 0 :(得分:33)

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

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

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

该约束定义适用于Rails 3.1

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

答案 1 :(得分:25)

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

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 Routing Guide第3.2节

中提到了这一点
  

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

答案 2 :(得分:2)

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

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

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