内部重定向与Rails 3

HMC*_*tch 11 routing vanity-url ruby-on-rails-3

我正在尝试在Rails 3中实现一个通用的虚荣URL系统.通用的意思是虚荣网址与特定模型无关.它类似于Vanities gem,我VanityUrlController从所有的虚荣网址中击中了它.不同的是,我不想做,从外部重定向foo.com/usernamefoo.com/users/1foo.com/product-namefoo.com/products/1.我想要虚荣网址,并让VanityUrlContoller做一个模仿相应show动作的内部重定向.

我知道我想要将内部重定向分配给哪个控制器和操作,但是实际调度它时遇到问题.这就是我现在所处的位置:

TargetController.new.process("show", request.env)
Run Code Online (Sandbox Code Playgroud)

它似乎开始处理新的"请求",但缺少关键部分......就像实际的请求对象一样.

任何想法或指示将非常感激.

更新:

我在ActionController中遇到了调度方法,这似乎让我更进一步.

TargetController.new.dispatch("show", request)
Run Code Online (Sandbox Code Playgroud)

我有两个问题,1)它被列为私有api方法,所以如果有另一种方法来做到这一点,我宁愿那样,2)即使它正在渲染TargetController的show模板,它是抱怨"缺少模板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
}
Run Code Online (Sandbox Code Playgroud)

您还需要在创建虚荣路线时小心,这样它们就不会与您的其他控制器发生碰撞.其他一些有用的知识是:

Rails.application.routes.routes.any? { |r| r.requirements[:controller] == vanity_url }
Run Code Online (Sandbox Code Playgroud)

它告诉您是否vanity_url与当前控制器具有相同的名称.

Rails.application.routes.recognize_path("/#{vanity_url}", :method => :get)
Run Code Online (Sandbox Code Playgroud)

这告诉你这是否已映射到任何东西.

当然,沿途有几个黑客,但它的作用就像一个魅力.

Fra*_*ock 1

尝试FriendlyId 插件。它似乎完全按照你想要的做。视频教程: http://railscasts.com/episodes/314-pretty-urls-with-Friendlyid