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



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

http://site.com/foobar 

而不是

http://site.com/users/foobar

foobar将是用户模型中nickname列中用户的昵称。如何防止用户注册顶级路由?比如联系、关于、注销等?

我可以有一个保留名称表。因此,当用户注册昵称时,它会对照此表进行检查。但是有没有更方便的方法呢?

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

上级:

如果任何路径似乎被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]尽管包含标题)。

最新更新