'Rails 7 + Devise Not seeing flash messages from devise

I have a new rails 7 app [rails new devisetest], a simple controller with static page and added devise [gem 'devise' + rails g devise user]. All defaults. Flash messages added to the application.html.erb as per devise instructions

Devise error messages are not being shown, but I see them being generated in the console (or at least, I see the rendered message but they don't show, and I see rendered for the _links partial and that does show) In another test using a quick scaffold (and having copied the devise views into the app but not modified them), flash messages show for the scaffold but still not for devise.

If I visit http://localhost:3000/users/sign_up and create a user with a too short password I see this in the log

Started POST "/users" for ::1 at 2021-12-24 08:02:10 +0000
Processing by Devise::RegistrationsController#create as TURBO_STREAM
  Parameters: {"authenticity_token"=>"[FILTERED]", "user"=>{"email"=>"[email protected]", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Sign up"}
  TRANSACTION (0.1ms)  begin transaction
  User Exists? (2.7ms)  SELECT 1 AS one FROM "users" WHERE "users"."email" = ? LIMIT ?  [["email", "[email protected]"], ["LIMIT", 1]]
  TRANSACTION (0.2ms)  rollback transaction
  Rendering layout layouts/application.html.erb
  Rendering /home/sroot/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/devise-4.8.1/app/views/devise/registrations/new.html.erb within layouts/application
  Rendered /home/sroot/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/devise-4.8.1/app/views/devise/shared/_error_messages.html.erb (Duration: 0.7ms | Allocations: 582)
  Rendered /home/sroot/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/devise-4.8.1/app/views/devise/shared/_links.html.erb (Duration: 0.2ms | Allocations: 92)
  Rendered /home/sroot/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/devise-4.8.1/app/views/devise/registrations/new.html.erb within layouts/application (Duration: 3.9ms | Allocations: 2199)
  Rendered layout layouts/application.html.erb (Duration: 77.5ms | Allocations: 4429)
Completed 200 OK in 473ms (Views: 78.7ms | ActiveRecord: 3.1ms | Allocations: 15288)

View that should show error message. Devise links are shown but not flash messages

Can anyone point out my mistake please? Or suggest other steps I can follow to get closer to my error?

Thanks



Solution 1:[1]

I have the same issue. It is someway linked with the compatibility of Rails 7.0 and Devise 4.8.1. I am unable to sign up a user. The sqlite3 database also remains empty, so I don't think its just the issue of flash messages and the users aren't being entered. Some people have addressed various issue with Rails 7 / Devise by adding the following to config/initializers/devise.rb:

config.navigational_formats = ['*/*', :html, :turbo_stream]

Solution 2:[2]

I am following the tutorials (video: https://gorails.com/episodes/devise-hotwire-turbo?autoplay=1) as well as tried it with this tutorial here: https://medium.com/@nejdetkadir/how-to-use-devise-gem-with-ruby-on-rails-7-33b89f9a9c13

But the flash messages or not showing up.

I added to my devise.rb now :

    # frozen_string_literal: true

    class TurboFailureApp < Devise::FailureApp
      def respond
        if request_format == :turbo_stream
          redirect
        else
          super
        end
      end

      def skip_format?
        %w(html turbo_stream */*).include? request_format.to_s
      end
    end


config.navigational_formats = ['*/*', :html, :turbo_stream]

  config.warden do |manager|
    manager.failure_app = TurboFailureApp
  #   manager.intercept_401 = false
  #   manager.default_strategies(scope: :user).unshift :some_external_strategy
  end

As well as created a devise_controller.rb:

class Users::DeviseController < ApplicationController
    class Responder < ActionController::Responder
      def to_turbo_stream
        controller.render(options.merge(formats: :html))
      rescue ActionView::MissingTemplate => error
        if get?
          raise error
        elsif has_errors? && default_action
          render rendering_options.merge(formats: :html, status: :unprocessable_entity)
        else
          redirect_to navigation_location
        end
      end
    end
  
    self.responder = Responder
    respond_to :html, :turbo_stream
  end

Solution 3:[3]

Follow this link for a workaround.

  1. create a controller to respond to html and turbo_stream
  2. modify config/initializers/devise.rb

Solution 4:[4]

If you just want it, "to work", you can add data: { turbo: false } to your devise form. This will prevent turbo from hijacking your form submissions with all it's automagic.

Credit to john-999 here https://github.com/heartcombo/devise/issues/5446#issuecomment-1083485163

In my case my views/devise/sessions/new.html.erb looked like:

    <%= form_for(resource, as: resource_name, url: session_path(resource_name), data: { turbo: false }) do |f| %>
      <% resource.errors.full_messages.each do |msg| %>
        <div><%= msg %></div>
      <% end %>

      <div class="mb-3">
        <%= f.label :email, class: "form-label" %>
        <%= f.email_field :email, autofocus: true, autocomplete: "email", class: 'form-control' %>
      </div>

      <div class="mb-3">
        <%= f.label :password, class: "form-label" %>
        <%= f.password_field :password, autocomplete: "current-password", class: 'form-control' %>
      </div>

      <div class="mb-4 mt-4">
        <%= f.submit t('.sign_in'), class: "btn btn-lg btn-primary" %>
      </div>
    <% end %>

Solution 5:[5]

Not at this point. I would recommend that you abstract this into a custom hook.

export function useGetDetails(){
  const { isLoading, data } = useGetAuthIdQuery()
  return useGetDetailsQuery(data, { skip: isLoading })
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Divij Jain
Solution 2 Sabrina
Solution 3 Jake Pillai
Solution 4 genkilabs
Solution 5 phry