将相同的表单提交给不同的操作
Submit same form to different actions
根据用户选择的 submit
按钮(在本例中为 Cat
和 Dog
),我想使用正确的 http 动词。
在这种情况下,只有一个文本输入。如果用户按 Cat
我想 POST
到 Cats#create
如果 Dog
到 PUT
到 Dogs#update
.
我将如何构建表单?
编辑
使用 formaction
属性我可以 PUT
到 Dogs#update
<%= form_for(cat) do |f| %>
<div class="field">
<%= f.label :name %>
<%= f.text_field :name %>
</div>
<div class="actions">
<%= f.submit "Cat" %>
<%= f.submit "Dog", formaction: dog_path(Dog.first) %>
<%#= f.submit "Cat", name: 'route_to[cat]' %>
<%#= f.submit "Dog", name: 'route_to[dog]' %>
</div>
<% end %>
问题是我想 POST
到 Dogs#create
,formaction
可以吗?
编辑
有一个 railscast 关于基于按下的按钮的名称构建控制器的逻辑。但我想将关于哪个 HTTP 动词、控制器和操作的逻辑放在提交按钮本身中。这可能吗?
您可以创建带有一些字段和提交按钮的简单表单。然后创建类似的表单,但带有隐藏字段,当用户填写第一个表单的字段(为此使用 javascript )和可见的提交按钮时,这些字段将被填充。因此用户填写第一个表单的可见字段,javascript 代码将值复制到第二个表单的相应隐藏字段。用户有两个提交可以点击。对于 @items
,您也可以隐藏字段并在 @items
值内手动设置字段值。
或者 替代解决方案,它适用于我的项目并且可能满足您的需求。要使用它,您需要引入一些 condition
,这将 "decide" 应该使用什么控制器和操作。
您的观点:
<% if condition %>
<%= form_tag controller: "foos", action: "create", method: :post %>
<%= render partial: 'form', locals: {button_name: "Foo"} %>
<% else %>
<%= form_tag controller: "bars", action: "update", method: :put do %>
<%= render partial: 'form', locals: {button_name: "Bar"} %>
<% end %>
您的 _form
部分:
<%# Your form and @items fields %>
<%= submit_tag button_name %>
该解决方案为您提供了一个表单和该表单的提交按钮。它将是什么形式(对于 Foos
或 Bars
)取决于 condition.
在这种情况下,创建 Cat
和更新 Dog
足够相关,因此在 CatsController
中使用 case statement 处理两者并使用:name
属性在 submit
按钮上。
例如:
app/views/cats/new.html.erb:
<%= form_tag(cats_path, multipart: true, role: "form") do %>
<%= button_tag 'Cat', name: 'route_to[cat]'%>
<%= button_tag 'Dog', name: 'route_to[dog]' %>
<% end %>
app/controllers/cats_controller.rb:
def create
case route_to params
when :cat
# create a cat
when :dog
# update a dog
end
end
.
.
.
private
def route_to params
params[:route_to].keys.first.to_sym
end
根据用户选择的 submit
按钮(在本例中为 Cat
和 Dog
),我想使用正确的 http 动词。
在这种情况下,只有一个文本输入。如果用户按 Cat
我想 POST
到 Cats#create
如果 Dog
到 PUT
到 Dogs#update
.
我将如何构建表单?
编辑
使用 formaction
属性我可以 PUT
到 Dogs#update
<%= form_for(cat) do |f| %>
<div class="field">
<%= f.label :name %>
<%= f.text_field :name %>
</div>
<div class="actions">
<%= f.submit "Cat" %>
<%= f.submit "Dog", formaction: dog_path(Dog.first) %>
<%#= f.submit "Cat", name: 'route_to[cat]' %>
<%#= f.submit "Dog", name: 'route_to[dog]' %>
</div>
<% end %>
问题是我想 POST
到 Dogs#create
,formaction
可以吗?
编辑
有一个 railscast 关于基于按下的按钮的名称构建控制器的逻辑。但我想将关于哪个 HTTP 动词、控制器和操作的逻辑放在提交按钮本身中。这可能吗?
您可以创建带有一些字段和提交按钮的简单表单。然后创建类似的表单,但带有隐藏字段,当用户填写第一个表单的字段(为此使用 javascript )和可见的提交按钮时,这些字段将被填充。因此用户填写第一个表单的可见字段,javascript 代码将值复制到第二个表单的相应隐藏字段。用户有两个提交可以点击。对于 @items
,您也可以隐藏字段并在 @items
值内手动设置字段值。
或者 替代解决方案,它适用于我的项目并且可能满足您的需求。要使用它,您需要引入一些 condition
,这将 "decide" 应该使用什么控制器和操作。
您的观点:
<% if condition %>
<%= form_tag controller: "foos", action: "create", method: :post %>
<%= render partial: 'form', locals: {button_name: "Foo"} %>
<% else %>
<%= form_tag controller: "bars", action: "update", method: :put do %>
<%= render partial: 'form', locals: {button_name: "Bar"} %>
<% end %>
您的 _form
部分:
<%# Your form and @items fields %>
<%= submit_tag button_name %>
该解决方案为您提供了一个表单和该表单的提交按钮。它将是什么形式(对于 Foos
或 Bars
)取决于 condition.
在这种情况下,创建 Cat
和更新 Dog
足够相关,因此在 CatsController
中使用 case statement 处理两者并使用:name
属性在 submit
按钮上。
例如:
app/views/cats/new.html.erb:
<%= form_tag(cats_path, multipart: true, role: "form") do %>
<%= button_tag 'Cat', name: 'route_to[cat]'%>
<%= button_tag 'Dog', name: 'route_to[dog]' %>
<% end %>
app/controllers/cats_controller.rb:
def create
case route_to params
when :cat
# create a cat
when :dog
# update a dog
end
end
.
.
.
private
def route_to params
params[:route_to].keys.first.to_sym
end