5

尝试在我的 Rails 路线中使用用户名。

正在运行的路线:

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规则

我知道我可以重新排序我的路线,以便 /signup 出现在之前,但这似乎有点 hacky。

有什么方法可以重写吗?或者是保留用户名验证的唯一方法?

谢谢

编辑

我最终使用保留字向用户模型添加了验证。命名空间是个好主意,但我不想污染我的 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
4

1 回答 1

8

路由按定义顺序具有优先级,较早的覆盖较晚。如果您希望您的/signup路径有效,则需要在路径之前定义它/:username。这不是hacky,这就是它的工作原理。

可以排除某些匹配:username项,但是如果列表很长,这会减慢您的路由速度,或者您必须将其重新编写为正则表达式,这可能是这里 hacky 的定义。

当您为任意用户名创建根路径时,您应该考虑为所有其他路由创建一个前缀,这样它们就不会发生冲突。例如,/=/signup/-/signup/_signup如果您在用户名的开头不允许使用下划线,您也可以使用类似的方法,或者使用其他定义排除项的方式来分配您的所有其他路由。

这样,您就不必担心在引入新功能之前检查用户数据库,或者创建一长串详尽的无效名称列表。

于 2013-05-28T15:51:19.260 回答