MISSION:

  • fix NoMethodError in Devise::RegistrationsController#create undefined method user_url’ for #<Devise::RegistrationsController:0x0000000000de58>`

  • fix No route matches [GET] "/users/sign_out"

  • fix sign_in - validation errors do not display

TLDR: add , data: { turbo: "false" } / "data-turbo" => "false" to Devise forms and buttons


I’ve been hearing that “devise & turbo don’t play well yet” for many months, and I just waited…

Well, it’s been 12 months since turbo was announced (Dec 20, 2020).

Now we have Turbo 7.0, Rails 7, and the Devise maintainer says that Devise is ready.

So, let’s try to install devise on a Rails 7 app (that uses Turbo by default).

1. Install gem devise #

Gemfile - use main

-- gem 'devise'
++ gem 'devise', github: 'heartcombo/devise', branch: 'main'
rails generate devise:install
rails generate devise User
rails db:migrate
# app/controllers/application_controller.rb
  before_action :authenticate_user!
  • Before, it was a simple link_to
  • Now, it has to be a button_to with data: { turbo: "false" }
# app/views/layouts/application.html.erb
  <% if signed_in? %>
    <%= link_to current_user.email, edit_user_registration_path %>
--  <%#= link_to "Log out", destroy_user_session_path, method: :delete %>
--  <%#= button_to "Log out", destroy_user_session_path, method: :delete, form: { "data-turbo" => "false" } %>
++  <%= button_to "Log out", destroy_user_session_path, method: :delete, data: { turbo: "false" } %>
  <% else %>
    <%= link_to "Log in", new_user_session_path %>
    <%= link_to "Register", new_user_registration_path %>
  <% end %>

Alternatively, you can try a link_to with data-turbo-method delete:

<%= link_to "Log Out", destroy_user_session_path, 'data-turbo-method': :delete %>
<%= link_to "Log out", destroy_user_session_path, data: { turbo_method: :delete } %>

3. BUT ALL DEVISE FORMS DO NOT WORK! #

We have to disable Turbo for devise (add data: {turbo: false} to all devise forms).

This is illustrated as a passable solution in this discussion.

rails generate devise:views
# rails generate devise:views -v confirmations passwords registrations sessions
# app/views/devise/registrations/new.html.erb
-- <%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
++ <%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { data: { turbo: false} } ) do |f| %>
# app/views/devise/sessions/new.html.erb
-- <%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
++ <%= form_for(resource, as: resource_name, url: session_path(resource_name), html: { data: { turbo: false} } ) do |f| %>

That’s it! Should work OK.

I’ve also updated the Devise Wiki

Yes, it is quite manual, but I do not see a better solution at the moment :(