如何防止配置文件URL与其他路由冲突

时间:2012-04-12 18:53:58

标签: ruby-on-rails ruby-on-rails-3 routes

如果我希望用户网址看起来像

http://site.com/foobar 

而不是

http://site.com/users/foobar

foobar将是用户模型中nickname列的用户的昵称。我如何阻止用户注册顶级路线?喜欢联系,关于,退出等?

我可以有一张保留名称表。因此,当用户注册昵称时,它将检查此表。但是有更方便的方法吗?

1 个答案:

答案 0 :(得分:1)

if(Rails.application.routes.recognize_path('nickname') rescue nil)
  # forbid using desired nickname
else
  # nickname can be used -- no collisions with existing paths
end

<强> UPD:

如果recognize_path似乎识别出任何路径,那么你就会得到类似的信息:

get ':nick' => 'user#show'

routes.rb的末尾,导致任何路径可路由的情况。要解决此问题,您必须使用约束。我会告诉你一个例子:

# in routes.rb
class NickMustExistConstraint
    def self.matches?(req)
        req.original_url =~ %r[//.*?/(.*)] # finds jdoe in http://site.com/jdoe. You have to look at this regexp, but you got the idea.
        User.find_by_nick $1
    end
end
get ':nick' => 'users#show', constraints: NickMustExistConstraint

通过这种方式,我们将一些动态添加到我们的路由系统中,如果我们有一个带有错误jdoe的用户,则会识别路由/jdoe。如果我们的用户没有rroe,则/rroe路径将无法路由。

但是如果我是你,我会做两件事:

# in User.rb
def to_param
  nick
end
# in routing.rb
resources :users, path: 'u'

它会让我能够获得像/u/jdoe这样的路径(这很简单,完全符合REST)。

在这种情况下,请确保您通过User.find_by_nick! params[:id]搜索您的用户(是的,它仍然是params[:id],但不幸的是包含了标题。