0

我目前有一个表格(使用 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])在我的控制器中运行相应的方法可能会起作用,但这不起作用,因为表单中的操作需要在设置参数值之前设置。我不想为这个功能使用 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
4

2 回答 2

1

警告:这是一个糟糕的主意

您可以通过控制器中这样的代码片段调用该方法:

send(params[:report_name].to_sym)

这是一个糟糕的想法的原因是任何访问该页面的人都可以通过注入一个调用危险的请求来手动构造一个调用任何方法的请求。你真的,真的不想这样做。你最好设置一些东西来动态调用你的表单中已知的、受信任的方法。

于 2013-02-01T01:16:36.240 回答
0

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

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

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

于 2013-02-01T01:16:53.327 回答