Подтвердить что ты не робот

Внутренние переадресации с Rails 3

Я пытаюсь реализовать общую систему URL-адресов тщеславия в Rails 3. Общий смысл в том смысле, что тщеславие не привязано к конкретной модели. Он похож на драгоценный камень Vanities, где у меня есть VanityUrlController, который ударил по всем тщеславиям. Разница в том, что я не хочу делать внешнюю переадресацию от foo.com/username до foo.com/users/1 или foo.com/product-name до foo.com/products/1. Я хочу, чтобы URL-адрес тщеславия оставался в стороне и имел VanityUrlContoller внутреннюю переадресацию, которая имитирует соответствующее действие шоу.

Я знаю, какой контроллер и какое действие я хочу отправить внутреннему перенаправлению, но у меня возникают проблемы с его отправкой. Вот где я сейчас:

TargetController.new.process("show", request.env)

Кажется, начинает обрабатывать новый "запрос", но отсутствуют ключевые фрагменты... как и фактический объект запроса.

Любые мысли или указатели будут очень оценены.

Update:

Я наткнулся на метод отправки в ActionController, который, кажется, немного меня ударил.

TargetController.new.dispatch("show", request)

У меня есть две проблемы с этим: 1) он указан как частный метод api, поэтому, если есть другой способ сделать это, я бы предпочел, и 2) даже если он отображает шаблон show для TargetController, он жалуется на "Отсутствует шаблон vanity_urls/show."

UPDATE

Вот основа решения, с которым мы столкнулись. Мы делаем некоторые другие вещи, такие как форсирование кодировок и проверка некоторых других конкретных приложений, но это должно быть все, что вам нужно для начала.

Это находится в самом низу вашего файла 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)

Что говорит вам, что это уже что-то сопоставляется.

Конечно, на пути есть пара хаков, но это работает как шарм.

4b9b3361