我需要有多个提交按钮。
我有一个创建Contact_Call实例的表单。
一键创建它正常。
另一个按钮创建了它,但是需要具有与默认值不同的:attribute值,并且还需要在控制器中使用的不同但相关的模型上设置属性。
我怎么做?我无法更改路线,因此有没有办法发送由[:params]接收的其他变量?
如果这样做,我将在控制器中做什么,设置一个case语句?
我需要有多个提交按钮。
我有一个创建Contact_Call实例的表单。
一键创建它正常。
另一个按钮创建了它,但是需要具有与默认值不同的:attribute值,并且还需要在控制器中使用的不同但相关的模型上设置属性。
我怎么做?我无法更改路线,因此有没有办法发送由[:params]接收的其他变量?
如果这样做,我将在控制器中做什么,设置一个case语句?
Answers:
您可以创建多个提交按钮,并为每个按钮提供不同的值:
<% 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
但是,请记住,这可能会使视图与控制器紧密耦合,这可能不是很理想。
还有另一种方法,使用“提交”按钮上的formaction属性:
<% form_for(something) do |f| %>
...
<%= f.submit "Create" %>
<%= f.submit "Special Action", formaction: special_action_path %>
<% end %>
代码保持整洁,因为标准的create按钮不需要任何更改,您只需为特殊按钮插入一个路由路径即可:
formaction:
处理输入元素提交的信息的程序的URI(如果它是提交按钮或图像)。如果指定,它将覆盖元素的表单所有者的action属性。资料来源:MDN
您也可以识别更改属性名称的按下按钮。
<% 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建议的类似解决方案,不使用任何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
注意,我避免使用值,而改用输入名称,因为提交按钮的值通常是国际化的/翻译的。另外,我会避免使用过多,因为它会很快使您的路线文件混乱。
我们解决了在Rails中使用高级约束的问题。
想法是具有相同的路径(因此也具有相同的命名路线和动作),但具有路由到不同动作的约束。
resources :plan do
post :save, constraints: CommitParamRouting.new("Propose"), action: :propose
post :save, constraints: CommitParamRouting.new("Finalize"), action: :finalize
end
CommitParamRouting
是一个简单的类,具有一个方法matches?
,如果提交参数与给定的实例attr相匹配,则该方法返回true。值。
这可以作为gem commit_param_matching使用。
一个古老的问题,但是由于我一直在处理相同的情况,所以我认为我应该发布解决方案。我使用控制器常量来避免在控制器逻辑和视图按钮之间引入差异。
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 %>
这样,文本仅存在于一个位置-作为控制器中的常量。但是,我还没有想出如何进行此操作。