Sometimes, when designing a form for your application, you might need both a SAVE and DELETE button within the same form.
You might be tempted to use something like this for the DELETE button:
<%= button_to "Delete", post_path(@post), method: :delete %>
The problem with this approach is that the button_to
Rails helper will generate this HTML in your form:
<input name="_method" type="hidden" value="delete" />
Nested forms aren't supported in HTML, and as a result, even when you click the SAVE button in your form, the hidden input will be sent with the request and the DELETE will be executed. Not good.
If you're using the Rails Unobtrusive JavaScript adapter (UJS), included starting with Rails 5.1, it's common to implement your DELETE button like this:
<%= link_to "Delete", post, method: :delete, data: { confirm: "Are you sure?" } %>
This relies on some javascript provided by UJS which intercepts the request and handles it for you.
Rails 7 doesn't include UJS, and if you're using Hotwire, you might have removed it. So, what to do?
One option is to separate the DELETE button's <label>
and <button>
tags so that the label is inside the form as desired for your layout, but the button is outside of it so that the SAVE and DELETE actions are no longer in nested forms, like this:
<%= form_with(model: post) do |form| %>
<!-- other form fields and stuff -->
<%= form.submit "Save" %>
<label for="delete">Delete</label>
<% end %>
<%= button_to "", post_path(post), :method => 'delete', id: 'delete' %>
Finally, I suggest checking out mrujs
. It bills itself as "Modern Ruby UJS" and replaces the functionality of UJS while co-existing with newer Rails libraries like Turbo. Install it, and you're back to being able to use the link_to
UJS example above, as well as the other goodies provided by UJS, like data-disable-with
, etc.
Some of this functionality seems to be on the Turbo roadmap, so we'll see how things develop in future releases.
Good luck!
Top comments (0)