如果我希望用户网址看起来像
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]
尽管包含标题)。