Внутренние перенаправления с Rails 3
Я пытаюсь реализовать общую систему тщеславных URL в Rails 3. Общая в том смысле, что URL тщеславия не привязан к конкретной модели. Это похоже на жемчужину тщеславия, где у меня есть VanityUrlController
это поражено от всех тщеславных URL. Разница в том, что я не хочу делать внешнее перенаправление с foo.com/username
в foo.com/users/1
или же foo.com/product-name
в foo.com/products/1
, Я хочу, чтобы URL-адрес тщеславия оставался без присмотра, и чтобы VanityUrlContoller выполнял внутреннее перенаправление, имитирующее соответствующее действие показа.
Я знаю, на какой контроллер и какое действие я хочу отправить внутреннее перенаправление, но у меня возникают проблемы с его отправкой. Вот где я сейчас нахожусь:
TargetController.new.process("show", request.env)
Кажется, он начинает обрабатывать новый "запрос", но отсутствуют ключевые элементы... как и сам объект запроса.
Любые мысли или указатели будут очень благодарны.
Обновить:
Я наткнулся на метод отправки в ActionController, который, кажется, немного продвинул меня вперед.
TargetController.new.dispatch("show", request)
У меня есть две проблемы с этим, 1) он указан как частный метод API, так что если есть другой способ сделать это, я бы предпочел, и 2) даже если он отображает шаблон шоу для TargetController, это жалуется на "Отсутствует шаблон vanity_urls/show."
ОБНОВИТЬ
Вот основы решения, которое мы придумали. Мы делаем некоторые другие вещи, такие как принудительное кодирование и проверка некоторых других специфических для приложения вещей, но это должно быть все, что вам нужно для начала работы.
Это идет в самом низу вашего routes.rb
файл, чтобы ваши тщеславие маршруты не засоряли ваши другие названные маршруты.
# Vanity routes.
match ':id', :as => 'vanity', :to => proc { |env|
id = env["action_dispatch.request.path_parameters"][:id]
vain_object = <method to find the object you want to display>
if vain_object.nil?
# render your 404 page
'application#404'
else
model = vain_object.class.model_name
# figure out the controller you want to go to
controller = [model.pluralize.camelize,"Controller"].join.constantize
# reset the :id parameter with the id of the object to be displayed
env["action_dispatch.request.path_parameters"][:id] = vain_object.id
# do your internal redirect
controller.action("show").call(env)
end
}
Вам также нужно быть осторожным при создании маршрутов тщеславия, чтобы они не сталкивались с другими вашими контроллерами. Некоторые другие полезные вещи, о которых нужно знать:
Rails.application.routes.routes.any? { |r| r.requirements[:controller] == vanity_url }
Который говорит вам, если ваш vanity_url
имеет то же имя, что и текущий контроллер.
Rails.application.routes.recognize_path("/#{vanity_url}", :method => :get)
Который говорит вам, если это соответствует чему-либо уже.
Конечно, на этом пути есть пара хаков, но это работает как шарм.
1 ответ
Попробуйте плагин FriendlyId. Кажется, делать именно то, что вы хотите. Видеоурок: http://railscasts.com/episodes/314-pretty-urls-with-friendlyid