如何在Rails中为同一个表单创build多个提交button?

我需要有多个提交button。

我有一个创buildContact_Call实例的表单。

一个button就像正常一样创build它。

另一个button创build它,但需要具有与默认值不同的:属性值,还需要在控制器中使用的另一个相关模型上设置该属性。

我怎么做? 我不能改变路线,那么有没有办法发送一个不同的variables,被[:params]拾取?

如果我这样做,我在控制器中做了什么,build立了一个案例陈述?

您可以创build多个提交button并为每个提供不同的值:

<% form_for(something) do |f| %> .. <%= f.submit 'A' %> <%= f.submit 'B' %> .. <% end %> 

这将输出:

 <input type="submit" value="A" id=".." name="commit" /> <input type="submit" value="B" id=".." name="commit" /> 

在控制器内部,提交的button的值将由参数commit来标识。 检查值以执行所需的处理:

 def <controller action> if params[:commit] == 'A' # A was pressed elsif params[:commit] == 'B' # B was pressed end end 

但是,请记住,这将您的观点与控制器紧密结合在一起,这可能不是很理想。

还有另一种方法,在提交button上使用formaction属性:

 <% form_for(something) do |f| %> ... <%= f.submit "Create" %> <%= f.submit "Special Action", formaction: special_action_path %> <% end %> 

代码保持干净,因为标准的创buildbutton不需要任何改变,你只需要为特殊button插入一个路由path:

formaction:
如果是提交button或图像,则处理由input元素提交的信息的程序的URI。 如果指定,则覆盖元素表单所有者的action属性 。 来源: MDN

您也可以识别更改其属性名称的button。

 <% form_for(something) do |f| %> .. <%= f.submit 'A', name: 'a_button' %> <%= f.submit 'B', name: 'b_button' %> .. <% end %> 

这有点不舒服,因为你必须检查参数键存在,而不是简单地检查params[:commit]值:您将收到params[:a_button]params[:b_button]取决于哪一个被按下。

@ vss123提供的类似解决scheme不使用任何gem:

 resources :plan do post :save, constraints: lambda {|req| req.params.key?(:propose)}, action: :propose post :save, constraints: lambda {|req| req.params.key?(:finalize)}, action: :finalize end 

请注意,我避免使用值并使用input名称,因为提交button值经常被国际化/翻译。 此外,我会避免使用这个太多,因为它会很快凌乱你的路线文件。

我们解决了在rails中使用高级约束 。

这个想法是有相同的path(因此有相同的命名路线和行动),但约束路由到不同的行动。

 resources :plan do post :save, constraints: CommitParamRouting.new("Propose"), action: :propose post :save, constraints: CommitParamRouting.new("Finalize"), action: :finalize end 

CommitParamRouting是一个简单的类,有一个matches?的方法matches? 如果提交参数匹配给定的实例attr,则返回true。 值。

这可以作为一个gemcommit_param_matching 。

一个古老的问题,但自从我处理同样的情况,我想我会张贴我的解决scheme。 我正在使用控制器常量来避免引入控制器逻辑和视图button之间的差异。

 class SearchController < ApplicationController SEARCH_TYPES = { :searchABC => "Search ABCs", :search123 => "Search 123s" } def search [...] if params[:commit] == SEARCH_TYPES[:searchABC] [...] elsif params[:commit] == SEARCH_TYPES[:search123] [...] else flash[:error] = "Search type not found!"] [...] end end [...] end 

然后在视图中:

 <% form_for(something) do |f| %> [...] <%= f.submit SearchController::SEARCH_TYPES[:searchABC] %> <%= f.submit SearchController::SEARCH_TYPES[:search123] %> [...] <% end %> 

这样,文本只能存在于一个地方 – 作为控制器中的一个常量。 但是,我还没有试图弄清楚如何在这方面呢。

由于使用了nested_form_fields,我的表单上的提交button数量是可变的,所以使用这个名字对我来说是不够的。 我最终在表单中包含了一个隐藏的input字段,并使用Javascript来填充表单,当其中一个表单提交button被按下时。