我目前有一个表单(使用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 %>
有什么建议吗?
我可以将我的控制器方法更改为如下所示 - 但实际调用控制器方法运行吗?我猜这不会运行,因为参数值以字符串形式返回......
def run_reports
params[:report_name]
end
警告:这是一个糟糕的主意
您可以通过控制器中的代码片段调用该方法,如下所示:
send(params[:report_name].to_sym)
这是一个糟糕的想法的原因是,任何访问该页面的人都可以通过注入调用危险事物的请求来手动构造调用任何方法的请求。 你真的,真的不想这样做。 您最好设置一些东西来动态调用表单中的已知受信任方法。
您应该重新考虑应用程序的设计(基于我对它的了解)。您有一个负责运行报告的控制器,这确实不应该。控制器用于管理 Web 服务器与应用其余部分之间的连接。
一种解决方案是编写一个名为 ReportGenerator 的新类,该类将运行报告并将结果交还给控制器,控制器将通过单个操作(例如 show
)运行任何可能的报告。如果需要变量视图,可以使用与不同类型的报表对应的部分。
至于报告生成器,你需要有点创意。最好的解决方案完全有可能是有一个单独的类来生成每种报告类型。