turbo: Turbo can't be disabled for links with method: post/delete

I’ve seen a few issues hovering around this issue (https://github.com/hotwired/turbo-rails/issues/31, https://github.com/hotwired/turbo/issues/45, https://github.com/hotwired/turbo/issues/74). But it seems that disabling turbo is not respected for links with non-GET methods.

I’m attempting to do the following:

link_to "Log Out", destroy_user_session_path, method: :delete, data: { turbo: false }

and the request is always processed as TURBO_STREAM:

Started DELETE "/users/sign_out" for ::1 at 2021-06-18 13:25:48 -0400
Processing by Users::SessionsController#destroy as TURBO_STREAM

If I use button_to instead of link_to, the disabling of turbo works properly.

Versions:

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 15
  • Comments: 20 (2 by maintainers)

Commits related to this issue

Most upvoted comments

<%= button_to "Delete", url, method: :delete, class: 'button med-button', "data-turbo": false %>

This code works for me, though if I change it to a link_to or remove the data-turbo line it doesnt redirect. Just data-turbo = false or just button_to doesnt work either, it has to be both. And for whatever reason I can’t figure out, it was somehow ending up at my show method for pages instead of redirecting to the page I specified. I dont understand why it just ignores redirects. Doesn’t even get in to the desired controller action.

@fabianzwodrei - I think this is an issue with Devise and XHR requests, and creates problems with Turbo since it uses XHR. Similar issue reported on Stack **Overflow.

I believe this is because devise does not include status in redirect_to wi the session destroy (DELETE) action?

see: ActionController::Redirecting

If you are using XHR requests other than GET or POST and redirecting after the request then some browsers will follow the redirect using the original request method. This may lead to undesirable behavior such as a double DELETE. To work around this you can return a 303 See Other status code which will be followed using a GET request.

redirect_to posts_url, status: :see_other
redirect_to action: 'index', status: 303

I’m not sure any changes to turbo would solve this.

I think your options are:

  1. Use button_to (instead of link_to). This works since button_to creates a POST request (instead of DELETE) with params[:_method] = 'DELETE'.
  2. Configure devise sign out via GET with link_to (config.sign_out_via = :get)
  3. MonkeyPatch Devise controller to include status in redirect_to

I’d imagine a few people will get caught out with Rails 7 like myself, clear explanation in the docs here.

  • turbo attempts to submit forms although it can be easily disabled by wrapping form
  • avoid using <%= link_to %> for anything other than get requests
  • use <%= button_to %> for post requests
<div data-turbo="false">
    <form>
       <a href="/" data-turbo="true">Enabled if needed</a>
   </form>
</div>

Same goes for all other non get requests (i.e. patch, delete)

I’d imagine a few people will get caught out with Rails 7 like myself, clear explanation in the docs here.

  • turbo attempts to submit forms although it can be easily disabled by wrapping form
  • avoid using <%= link_to %> for anything other than get requests
  • use <%= button_to %> for post requests
<div data-turbo="false">
    <form>
       <a href="/" data-turbo="true">Enabled if needed</a>
   </form>
</div>

The team added support for links and POST|PUT|PATCH|DELETE in v7.0.0-beta.6

see: https://github.com/hotwired/turbo/releases/tag/v7.0.0-beta.6

I pulled down 7.0.0-beta.6 and it looks like the rails server is still processing the actions as TURBO_STREAM.

@efatsi did the new release fixed this for you?

In my case, it does work, but it’s still processing the delete as turbo_stream. Which caused my flash message to disappear (it redirects twice).

For me works only forcing redirect to html format in sessions controller, like below:

# app/controllers/users/sessions_controller.rb

def destroy
    signed_out = (Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name))
    set_flash_message! :notice, :signed_out if signed_out
    yield if block_given?
    respond_to_on_destroy
end


private

def respond_to_on_destroy
    respond_to do |format|
	format.all { redirect_to root_path(format: :html) }
    end
end

It’s work for me 100% <%= link_to “Logout”, destroy_user_session_path, method: “DELETE”, data: { “turbo-method”: “DELETE” } %>

Using 7.0.0-beta.6: My sign-out link for devise is working with the data-turbo-method but its reponse comes via TUBRO_STREAM and the following redirection is misguided by keeping the DELETE method.

<%= link_to "Logout", destroy_user_session_path, method: "DELETE", data: {"turbo-method": "DELETE"}%>

log:

Started DELETE "/users/sign_out?locale=en" for 127.0.0.1 at 2021-08-30 21:12:59 +0200
Processing by Devise::SessionsController#destroy as TURBO_STREAM
  Parameters: {"locale"=>"en"}
  User Load (0.4ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 2], ["LIMIT", 1]]
Redirected to http://localhost:3000/?locale=en
Completed 302 Found in 5ms (ActiveRecord: 0.4ms | Allocations: 1858)


Started DELETE "/?locale=en" for 127.0.0.1 at 2021-08-30 21:12:59 +0200
  
ActionController::RoutingError (No route matches [DELETE] "/"):

@efatsi did the new release fixed this for you?

In my case, it does work, but it’s still processing the delete as turbo_stream. Which caused my flash message to disappear (it redirects twice).