Как удалить имена контроллеров из маршрутов рельсов?
Я хотел бы обрезать маршруты в своем приложении, чтобы:
http://myapplication.com/users/peter/info/how-do-i-create-urls
становится...
http://myapplication.com/peter/how-do-i-create-urls
У меня есть пользовательский контроллер и хотел бы, чтобы он был находчив. Пользователи также имеют вложенный ресурс, называемый вопросами.
Файл основных маршрутов
Без корректировки URL-адресов файл маршрутов выглядит так:
...
resources :users do
resources :questions
end
Однако URL-адреса этого типа имеют вид
http://myapplication.com/users/peter/info/how-do-i-create-urls
а не
http://myapplication.com/peter/how-do-i-create-urls
Частичный успех
Я попытался сделать следующее:
...
resources :users, :path => '' do
resources :questions
end
Это работает и производит:
http://myapplication.com/peter/info/how-do-i-create-urls
Однако, если я попытаюсь:
...
resources :users, :path => '' do
resources :questions, :path => ''
end
Тогда все начинает идти не так.
Это правильный подход, и если да, то можно ли это сделать и с вложенными ресурсами?
Ответы
Ответ 1
То, как вы это делаете, должно работать. Я не знаю, какую проблему вы испытываете, но если вы скопировали код примера из вашего приложения напрямую, это может быть из-за дополнительного end
, который вы положили на свои маршруты. Вероятно, это должно выглядеть так:
resource :users, :path => '' do
resource :questions, :path => ''
end
Еще одна вещь, которая может быть причиной, и что вам нужно быть осторожным, заключается в том, что эти маршруты в значительной степени улавливают все запросы, и вы должны иметь их последние на своих маршрутах .rb, чтобы в первую очередь совпадали другие маршруты. Возьмите этот сценарий, например:
resource :users, :path => '' do
resource :questions, :path => ''
end
resources :posts
Если вы сделаете это таким образом, ни один запрос не будет перенаправлен на контроллер сообщений, так как запрос /posts/ 1 будет отправлен на контроллер вопросов с помощью: user_id = > 'posts',: id = > 1
Edit:
Кроме того, теперь я заметил, что вы используете ресурс вместо ресурсов. Не знаю, предназначено ли это или если это ошибка.
Ответ 2
Спасибо и @mark и @DanneManne за помощь. С их помощью и немного большим количеством настроек я получил все это. Это не совсем тривиально, но я не уверен, что вы могли бы сделать его намного короче:
Конечный рабочий код
# setup the basic resources while holding some back for creation below
resources :users, :except => [:show, :index, :new, :create], :path => '/' do
resources :questions, :except => [:show]
end
# for clarity, pick out routes that would otherwise go
# to root (such as new_user => '/new')
resources :users, :only => [:index, :new, :create]
# setup questions#show to give clean URLS
match ':user_id/:question_id', :as => :user_question,
:via => :get,
:controller => :questions,
:action => :show
# setup users#show method to give clean URLS
match ':user_id', :as => :user,
:via => :get,
:controller => :user,
:action => :show
Выход Rake Routes
user_questions GET /:user_id/questions(.:format) {:action=>"index", :controller=>"questions"}
POST /:user_id/questions(.:format) {:action=>"create", :controller=>"questions"}
new_user_question GET /:user_id/questions/new(.:format) {:action=>"new", :controller=>"questions"}
edit_user_question GET /:user_id/questions/:id/edit(.:format) {:action=>"edit", :controller=>"questions"}
user_question PUT /:user_id/questions/:id(.:format) {:action=>"update", :controller=>"questions"}
DELETE /:user_id/questions/:id(.:format) {:action=>"destroy", :controller=>"questions"}
edit_user GET /:id/edit(.:format) {:action=>"edit", :controller=>"users"}
user PUT /:id(.:format) {:action=>"update", :controller=>"users"}
DELETE /:id(.:format) {:action=>"destroy", :controller=>"users"}
users GET /users(.:format) {:action=>"index", :controller=>"users"}
POST /users(.:format) {:action=>"create", :controller=>"users"}
new_user GET /users/new(.:format) {:action=>"new", :controller=>"users"}
user_question GET /:user_id/:question_id(.:format) {:controller=>"questions", :action=>"show"}
user GET /:user_id(.:format) {:controller=>"user", :action=>"show"}
Ответ 3
Не уверен в вложенности, но попробуйте
:path => '/'
Ответ 4
Просто подумал, что добавлю еще одно возможное решение, если кто-то еще приедет из Google позднее.
После просмотра этой вложенной статьи ресурсов это может быть более чистое решение с почти такой же гибкостью в маршрутах:
resources :users, :path => ''
resources :users, :path => '', :only => [] do
resources :questions, :path => '', :except => [:index]
В принципе, включив второй родительский блок, дочерние ресурсы не будут выдаваться перед родительскими ресурсами.
В этом конкретном примере также предполагается, что наличие полных маршрутов для родительского блока более важно, чем для ребенка. Следовательно, дочерний блок ограничен индексом, но это может быть приемлемым, в зависимости от ситуации.