我正在尝试在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)
似乎开始处理新的“请求”,但有一些关键的部分丢失,像实际的请求对象.
任何想法或指针都将非常感激.
更新:
我碰到了ActionController中的调度方法,这似乎让我更远一些.
TargetController.new.dispatch("show",request)
我有两个问题,1)它被列为私人api方法,所以如果有另一种方式来做到这一点,我宁愿,和2)即使它是渲染目标控件的显示模板,它是抱怨“Missing template vanity_urls / show”.
UPDATE
以下是我们提出的解决方案的基础知识.我们做一些其他的事情,如强制编码和检查一些其他应用程序特定的东西,但这应该是你需要的所有去.
这是在你的路线.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)
哪个告诉你这是否已经映射到任何东西.
当然,一路上有几个黑客,但它的作用就像一个魅力.