2013-05-28 6 views
4

Пытается использовать имя пользователя в моих маршрутах.Rails имя пользователя в URL

Маршруты, которые работают:

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 правила

Я знаю, что может изменить порядок своих маршрутов так что/регистрация появляется раньше, но это кажется немного взломанным.

Есть ли способы переписать это? Или это единственный способ иметь зарезервированную проверку имен пользователей?

Благодаря

EDIT

Я в конечном итоге добавив проверки в пользовательской модели с зарезервированными словами. Пространство имен - хорошая идея, но я не хочу загрязнять свои URL.

Для записи Twitter пространства имен не-имена пользователей, как это: twitter.com/i/discover (идет в Twitter открыть раздел) twitter.com/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 
+3

А что, если мое имя пользователя «Регистрация» или любой другой реальный путь вашего приложения? Чтобы избежать таких конфликтов, я настоятельно рекомендую вложить эти пути в их собственное пространство имен. – christianblais

+1

Это не хаки. Так должен работать файл маршрутов. Вы можете добавить условие регулярного выражения на строку 'get '/: username' ', чтобы исключить'/signup', но это было бы полностью избыточным, чтобы иметь «get»/signup «» раньше. – depa

+0

Согласен; ничего не взломано: маршруты обрабатываются по порядку. –

ответ

7

Маршруты имеют приоритет в порядке определения, с более ранним переопределением позже. Если вы хотите, чтобы ваш путь /signup работал, его необходимо определить до /:username. Это не хаки, это как раз то, как это работает.

Можно исключить определенные совпадения для :username, но это замедляет вашу маршрутизацию, если список длинный, или вам придется переписать его как регулярное выражение, что, вероятно, является определением хакки Вот.

Когда вы создаете корневые пути для произвольных имен пользователей, вы должны подумать о создании префикса для всех ваших других маршрутов, чтобы они не конфликтуют. Например, /=/signup или /-/signup. Вы также можете использовать что-то вроде /_signup, если вы запретили подчеркивание в начале имени пользователя или какой-либо другой способ определения исключения, которое вы можете использовать для назначения всех ваших других маршрутов.

Таким образом вам не придется беспокоиться о проверке базы данных пользователей перед тем, как вводить новую функцию или создать длинный исчерпывающий список недопустимых имен.

+0

Спасибо за это. Это то, чего я боялся быть честным. Я считаю, что '/ -/signup' является своего рода уродливым (я такой странный), поэтому я думаю, что мне придется добавить валидацию в мою модель пользователя с массивом зарезервированных слов. –

+0

Это отвратительно, но к этому привыкнешь. Вы также можете нажимать на все свои не-пользовательские маршруты через субдомен или использовать префикс типа '.signup' или' ~ signup', если это выглядит лучше. – tadman

+0

Ах, только что заметил, что Twitter делает это, поэтому я чувствую себя лучше. Pinterest делает объекты с зарезервированными именами. Думаю, время перевернуть монету. Предположим, что только люди, подобные нам, обращают внимание на URL-адреса. –

Смежные вопросы