2011-02-14 84 views
10

我想在Rails 3中实现一个通用的虚荣URL系统。泛型的意义上,虚荣URL不绑定到特定的模型。它类似于Vanities的宝石,我有一个VanityUrlController从所有的虚荣网站中击中。区别在于我不想做一个从foo.com/usernamefoo.com/users/1foo.com/product-namefoo.com/products/1的外部重定向。我希望虚荣URL能够坚持下去,让VanityUrlContoller做一个内部重定向,模仿相应的显示操作。与Rails的内部重定向3

我知道什么控制器和动作我想分配内部重定向到,但我有实际调度它的问题。这是我的时刻,其中:

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

它似乎开始处理新的“请求”,但也有关键件失踪......像实际的请求对象。

任何想法或指针将不胜感激。

更新:

我在对面ActionController的调度方法,这似乎让我有点远跑。

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

我有两个问题,1),它被列为私有API方法,所以如果有另一种方式来做到这一点,我宁愿认为,和2),即使它被渲染秀TargetController的模板,它抱怨“Missing template 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) 

它告诉你这是否映射到任何东西。

当然,一路上有几个黑客,但它像一个魅力。

+0

下面是一个类似的选项,lambda提取出来并约束应用http://stackoverflow.com/questions/5641786/testing-rack-routing-using-rspec – Agustin 2012-03-30 17:17:38

回答