Depending on which submit
button a user selects, (Cat
and Dog
in this case), I'd like to submit the form to the right controller action using the right http verb.
In this case, there is one text input. If the user presses Cat
I'd like to POST
to Cats#create
and if Dog
to PUT
to Dogs#update
.
How would I build the form?
Edit
Using the formaction
attribute I'm able to PUT
to 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 %>
The problem is I want to POST
to Dogs#create
, is this possible with formaction
?
Edit
There is a railscast about building the logic the controller based on the name of the button pressed. But I want to put the logic about which HTTP verb, controller, and action in the submit button itself. Is this possible?
You could create the simple form with some fields and submit button. And then create similar form but with hidden fields which will be filled when user fills the first form's fields (use javascript for that) and visible submit button. So user fills the first form visible fields, javascript code copies the values to the second form's corresponding hidden fields. User has two submits to click on. For @items
you could have hidden fields too and manually set fields' values within @items
values.
Or an alternative solution which works in my project and could fit your needs probably. To use it you need to introduce some condition
which will "decide" what controller and action should be used.
Your view:
<% 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 %>
Your _form
partial:
<%# Your form and @items fields %>
<%= submit_tag button_name %>
That solution gives you one single form and submit button for this form. What form it will be (for Foos
or Bars
) depends on condition.
In this case creating a Cat
and updating a Dog
were related enough that it makes sense to handle both in the CatsController
with a case statement and use a :name
attribute on on the submit
button.
For example:
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