尝试在我的铁路路线中使用用户名。
正在运作的路线:
resources :users, only: [:show, :create, :update, :destroy]
get "/:username" => "users#show", as: :user
get "/:username/account" => "users#account", as: :user_account
get "/:username/interests", to: "users#interests", as: :user_interests
get "/:username/offers" => "users#offers", as: :user_offers
get "/:username/trades" => "users#trades", as: :user_trades
但现在是这样的路线:
get "/signup"
与/:username
规则匹配
我知道我可以重新排序我的路线,以便之前出现/注册,但这看起来有点笨拙。
我有什么办法可以改写吗?或者是保留用户名验证的唯一方法?
由于
修改
我最后使用保留字向用户模型添加了验证。命名空间是一个好主意,但我不想污染我的URL。
对于记录,Twitter命名空间非用户名如下: twitter.com/i/discover(转到Twitter发现部分) twitter.com/discover(转到@ discover的个人资料)
Pinterest保留名称,例如“搜索”,据我所知
我遵循Pinterest的方法代码:
验证
validate :reserved_username
private
def reserved_username
reserved_usernames = %w[index show create destroy edit update signup interests interest item items search offers offer community about terms privacy admin map authentication]
errors.add(:reserved_username, "username is reserved for the app") if reserved_usernames.include?(username)
end
答案 0 :(得分:7)
路由按照定义的顺序具有优先级,稍后会覆盖。如果您希望/signup
路径起作用,则需要在/:username
路径之前定义。这不是hacky,这就是它的工作原理。
可以排除:username
的某些匹配,但如果列表变长,这会减慢您的路由,或者您必须将其重新编写为正则表达式,这可能是hacky的定义。
当您为任意用户名创建根路径时,您应该考虑为所有其他路由创建前缀,以便它们不会发生冲突。例如,/=/signup
或/-/signup
。如果您在用户名的开头不允许使用下划线,或者您可以使用其他方式定义您可以用来分配所有其他路线的排除方式,也可以使用/_signup
之类的内容。
通过这种方式,您无需担心在引入新功能之前检查用户数据库,也无需创建详尽无遗的详尽无效名称列表。