我需要有多个提交按钮。
我有一个表单,用于创建Contact_Call的实例。
一个按钮可以正常创建。
另一个按钮创建它但需要具有默认的不同:属性值,并且还需要在控制器中使用的不同但相关的模型上设置属性。
我该怎么做?我无法改变路线,所以有没有办法发送一个由[:params]拾取的另一个变量?
如果我这样做,我在控制器中做什么,设置一个案例陈述?
答案 0 :(得分:122)
您可以创建多个提交按钮,并为每个按钮提供不同的值:
<% 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" />
在控制器内部,提交的按钮的值将由参数commit
标识。检查值以执行所需的处理:
def <controller action>
if params[:commit] == 'A'
# A was pressed
elsif params[:commit] == 'B'
# B was pressed
end
end
但是,请记住,这会将您的视图与控制器紧密结合,这可能并不理想。
答案 1 :(得分:58)
还有另一种方法,使用提交按钮上的formaction属性:
<% form_for(something) do |f| %>
...
<%= f.submit "Create" %>
<%= f.submit "Special Action", formaction: special_action_path %>
<% end %>
代码保持干净,因为标准的创建按钮不需要任何更改,您只需为特殊按钮插入路由路径:
formaction:
处理输入元素提交的信息的程序的URI(如果它是提交按钮或图像)。如果已指定,则会覆盖元素的表单所有者的操作属性。 资料来源:MDN
答案 2 :(得分:29)
您也可以识别按下哪个按钮更改其属性名称。
<% form_for(something) do |f| %>
..
<%= f.submit 'A', name: 'a_button' %>
<%= f.submit 'B', name: 'b_button' %>
..
<% end %>
有点不舒服,因为你必须检查params键存在而不是简单地检查params[:commit]
值:你会收到params[:a_button]
或params[:b_button]
,具体取决于按下了哪一个。< / p>
答案 3 :(得分:12)
与@ vss123建议的类似解决方案,不使用任何宝石:
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
请注意,我避免使用值并使用输入名称,因为提交按钮值通常是国际化/翻译的。此外,我会避免使用太多,因为它会很快混乱你的路线文件。
答案 4 :(得分:9)
我们在rails中使用advanced constraints解决了。
我们的想法是拥有相同的路径(因此具有相同的命名路由和操作),但约束路由到不同的操作。
resources :plan do
post :save, constraints: CommitParamRouting.new("Propose"), action: :propose
post :save, constraints: CommitParamRouting.new("Finalize"), action: :finalize
end
CommitParamRouting
是一个简单的类,它有一个方法matches?
,如果commit参数匹配给定的实例attr,则返回true。值。
这可用作宝石commit_param_matching。
答案 5 :(得分:3)
一个老问题,但由于我一直在处理同样的情况,我想我会发布我的解决方案。我使用控制器常量来避免在控制器逻辑和视图按钮之间引入差异。
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 %>
这样文本只存在于一个地方 - 作为控制器中的常量。然而,我还没有试图弄清楚如何使用它。
答案 6 :(得分:1)
由于nested_form_fields,我的表单上有一个可变数量的提交按钮,因此仅使用该名称对我来说还不够。我最终在表单中包含一个隐藏的输入字段,并在按下其中一个表单提交按钮时使用Javascript填充它。