Destroy action
There are 2 alternatives to create an action button (or link) for :destroy
:
-
create a mini form with
button_to
, or -
use link_to with some special data attributes
button_to
- Pros
-
-
use POST instead of GET for proper redirection
-
simple to use
-
- Cons
-
-
Creates a small form, so don’t use it within another form
-
Confirmation
data-turbo-confirm
needs to go to the form, not to the button. -
Needs a little more CSS styling to be compatible with other bootstrap link buttons
-
button_to 'Destroy', @post,
method: :delete,
form: { 'data-turbo-confirm': 'Are you sure?' }
form.button_to {
display: inline-block;
}
link_to
- Pros
-
-
No separate form
-
mostly compatible with older
rails-ujs
styles
-
- Cons
-
-
Beware of the 303 trap (see below)
-
link_to 'Destroy', @post,
'data-turbo-method':
'data-turbo-confirm': 'Are you sure?'
The 303 trap of @hotwired/turbo
If you are sending a DELETE
request via link_to … method: :delete
, Rails
redirects with a 302 redirect, but Turbo needs a 303 to use GET
after DESTROY
.
Otherwise Turbo generates a new DELETE
request. For example:
First Request | Turbo answer | Result |
---|---|---|
|
|
|
|
|
|
For more informations, see https://github.com/hotwired/turbo/issues/84 |
As long Rails uses 302 instead of 302 here, you have to made a choice:
-
set the correct redirect code in each controller (yeah, don’t like it too)
-
Catch the response and change it for get requests (see below)
-
use
button_to
instead oflink_to
class ApplicationController < ActionController::Base
def redirect_to(url_options = {}, response_options = {})
response_options[:status] ||= :see_other unless request.get?
super url_options, response_options
end
end