我目前有一个表单(使用form_tag)。其中一个字段是选项下拉列表。每个选项值都与控制器中方法的名称相匹配。我想要做的是当单击表单提交按钮时,它运行的控制器方法直接对应于下拉字段中选择的值。
我现在已经建立了解决方案,但感觉太冗长了:
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
答案 0 :(得分:1)
警告:这是一个糟糕的主意
您可以通过控制器中的代码片段调用该方法:
send(params[:report_name].to_sym)
这是一个可怕的想法的原因是访问该页面的任何人都可以手动构建一个请求来调用任何方法通过注入一个请求来调用危险的东西。你真的,真的不想这样做。您最好设置一些动态调用表单中已知的可信方法。
答案 1 :(得分:0)
我认为您应该重新考虑应用程序的设计(基于我所知道的一点点)。你有一个控制器负责运行报告,它实际上不应该。控制器用于管理Web服务器与应用程序其余部分之间的连接。
一种解决方案是编写一个名为ReportGenerator的新类,它将运行报告并将结果交还给控制器,控制器将通过单个操作运行任何可能的报告(例如,show
) 。如果您需要变量视图,则可以使用与不同类型的报告相对应的部分。
对于ReportGenerator,您需要有点创意。完全有可能最好的解决方案是让一个单独的类生成每种报告类型。