2009-10-10 50 views
2

我需要为预期丑陋的嵌套参数名称(这是设置,而不是我可以在这个时候改变的)的行动创建一个漂亮的路线。Rails命名路线使用复杂的参数名称

所以不是

http://domain.com/programs/search?program[type]=leader&program[leader_id]=12345 

我想

http://domain.com/programs/search/leader/12345 

的问题是Rails的路线定义不会处理复杂的参数名称。

map.programs 'programs/:program[type]/:program[leader_id]', :controller=>..., :action=>... 

同样,我不能够改变控制器 - 它的成立期望基于一组预先存在的搜索表单,这些参数的名称。我只想为一些预定义的搜索创建更具可读性的路线。

当然,必须有一种方法来创建一个路径,将输入数据传递给名称比单字母-alpha-alpha更复杂的参数。

回答

2

从我所收集你的帖子,你要像

http://domain.com/programs/search/leader/12345

的URL产生params散列,像

:params => { programs => {:type => "search", :leader_id => "12345"}} 

我不认为这是可以做到做。据我所知,你不能从named_route产生一个嵌套的散列。有解决方法,但每个都需要以某种方式修改控制器。

我觉得这是侵入性最小的解决方案: 首先设置一个简单的命名路由,

map.programs 'programs/:program_type/:program_leader_id', 
    :controller=>..., :action=>... 

然后,我会希望做一个的link_to或url_for包装可以作为一个辅助,因此可以通过一个程序对象,并使正确的网址。

def link_to_programs name, prog 
    link_to name, programs_url(prog, 
    :programs =>{:program_type => prog[:type], :prog[:program_leader_id]}) 
end 

然后,我会需要一些欺骗控制器的方式,因为它认为它通过了更深的params散列。

在programs_controller:

def fix_bad_params 
    params.merge!({:programs => {:type => params[:program_type], 
    :leader_id => params[:program_leader_id]) 
end 

before_filter :fix_bad_params, :only => :action_in_named_route 

NB。我列出的link_to包装不完整。我用它做了一个简单的演示。如果你打算将其他选项传递给它,或者甚至以其他方式使用它(例如:link_to(@project),则需要重写它。查看link_to来源以了解最佳做法它

+0

那么,现在你指出了嵌套哈希示例,我想知道是否可以使用嵌套路由完成。 否则您在控制器中的示例看起来像一个合理的选项。尽管理想情况下我会找到一个类似的解决方案,完全可以在路由定义中处理,并完全脱离控制器。例如: map.programs'programs /:type /:id',:remap => {:type =>'programs [type]',:id =>'programs [leader_id]'} 幸运的是,我不必担心路由助手和包装。这种特殊情况是客户将可读链接嵌入到其静态html中。 – wbr 2009-10-11 02:56:26

+0

我只是建议使用wrapper来使用common rails语法来动态生成链接。嵌套路由将不起作用,因为它们仍然只会创建浅的params散列。至于:重映射选项。这是可能的,但你需要修改处理routes.rb的代码。 Rails源代码可能难以解读。 – EmFi 2009-10-11 03:34:27

+0

哇,时光飞逝...上述两个答案都非常有帮助。我最终创建了一个友好的路线'workshop/search /:search_type/* criteria'加上ProgramsController中的before_filter,以便在将查询发送到程序模型之前重新排列查询....如果StackExchange给了我们一些通知单击“保存注释”并出现错误之前的编辑时间限制。 – wbr 2014-07-16 23:53:23

2

内置的路由机制不会做你想找的东西,恐怕你肯定是可能是猴子补丁的路由机制,但这似乎很多工作和很容易导致出现其他错误

你有没有想过过滤器配合更漂亮的路线?例如:

# in config/routes.rb: 
map.connect '/programs/:program_type/leader/:program_leader_id', ... 

# in config/initializers/translate_pretty_program_routes.rb 
module TranslatePrettyProgramRoutes 
    def self.included(base) 
    base.send :include, TranslatePrettyProgramRoutes::InstanceMethods 
    base.send :prepend_before_filter, :translate_pretty_program_route_params 
    end 

    module InstanceMethods 
    def translate_pretty_program_route_params 
     params[:program] ||= {} 
     params[:program][:type] ||= params[:program_type] 
     params[:program][:leader_id] ||= params[:program_leader_id] 
    end 
    end 
end 

# in app/controllers/programs_controller.rb: 
class ProgramsController < ApplicationController 
    include TranslatePrettyProgramRoutes 
end 

的元编程在TranslatePrettyProgramRoutes是要解决在发展模式类的重载问题。如果它不是用于类重新加载的,则可以定义该方法并在初始化程序中将其添加为before_filter