Внутренние перенаправления с Rails 3

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

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

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)

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

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

11
задан HMCFletch 6 March 2011 в 05:13
поделиться