2013-02-01 30 views
0

我目前有一个表单(使用form_tag)。其中一个字段是选项的下拉列表。每个选项值都与我的控制器中的方法名称相匹配。我想要做的是点击表单提交按钮时,它会运行控制器方法直接对应于下拉字段中选定的值。使用params [:value]引用Rails中的控制器方法

我已经建立了一个变通的权利,但感觉太冗长:

def run_reports 
    case params[:report_name] 
    when 'method_1' then method_1 
    when 'method_2' then method_2 
    when 'method_3' then method_3 
    when 'method_4' then method_4 
    else method_1 
end 
# each method matches a method already defined in the controller 
# (i.e. method_1 is an existing method) 

我原以为它可能工作使用下拉选项值通过运行在我的控制器中的相应方法form_tag操作(即:action => params [:report_name]),但这不起作用,因为需要在设置params值之前设置表单中的操作。我不想为此功能使用JavaScript。

这里是我的形式:

<%= form_tag("../reports/run_reports", :method => "get") do %> 
    <%= select_tag :report_name, options_for_select([['-- Please Select --',nil],['Option 1','method_1'], ['Option 2','method_2'], ['Option 3','method_3'], ['Option 4','method_4']]) %> 
    <%= submit_tag "Run Report" %> 
<% end %> 

有什么建议?

我可以改变我的控制器方法看起来像这样 - 但实际调用控制器方法运行?我猜这将无法运行,因为PARAMS值作为字符串返回...

def run_reports 
    params[:report_name] 
end 

回答

1

警告:这是一个可怕的想法

你可以通过一个片段调用的方法像这样的代码在控制器:

send(params[:report_name].to_sym) 

的原因,这是一个可怕的想法是,任何人访问该页面可通过手动构造提出请求,要求injec致电在所有任何方法请求调用危险的请求。你真的,真的不想这样做。你最好设置一些动作来调用表单中已知的,可信的方法。

+0

非常好的一点。 –

+0

请注意,如果您首先验证'params [:report_name]'是否已知是安全的,那么通过将其与可信方法列表进行核对,这可不是一个可怕的想法。我不相信这是干净的设计,但很难确切知道你想要做什么。 –

+0

谢谢吉姆。我猜想学习曲线的一部分不仅仅是学习如何用轨道做东西,还包括它是不是一个好主意。我一定会考虑你的建议,只处理可信任的方法。 – 2scottish

0

我认为你应该重新考虑你的应用程序的设计(基于我对它的了解)。你有一个负责运行报表的控制器,它实际上不应该这样做。控制器将管理Web服务器和其他应用程序之间的连接。

一种解决方案是编写一个名为ReportGenerator的新类,它将运行报告并将结果传回给控制器,控制器将通过单个操作(例如show)运行任何可能的报告。如果您需要变量视图,则可以使用与不同类型的报告对应的部分。

至于ReportGenerator,您需要有点创意。最好的解决方案完全有可能是让一个班级生成每种报告类型。

+0

谢谢Zach。我很可能很快就会重新构建网站。我只是想先把一些东西当作概念证明。 – 2scottish

相关问题