DEV Community

Travis Smith
Travis Smith

Posted on

Rails Nested DELETE Button without UJS

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 %>
Enter fullscreen mode Exit fullscreen mode

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" />
Enter fullscreen mode Exit fullscreen mode

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?" } %>
Enter fullscreen mode Exit fullscreen mode

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' %>
Enter fullscreen mode Exit fullscreen mode

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!

Discussion (0)