Rails 7 + 设计没有看到来自设计的闪存消息

我有一个新的 rails 7 应用程序 [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"=>"asdf@asdf.com", "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", "asdf@asdf.com"], ["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

谁能指出我的错误?或者建议我可以遵循的其他步骤来更接近我的错误?

谢谢

stack overflow Rails 7 + Devise Not seeing flash messages from devise
原文答案

答案:

作者头像

我正在关注教程(视频: https://gorails.com/episodes/devise-hotwire-turbo?autoplay=1 )并在此处使用本教程进行了尝试: https://medium.com/@nejdetkadir/how-to-use-devise-gem-with-ruby-on-rails-7-33b89f9a9c13

但是flash消息还是没有显示出来。

我现在添加到我的 devise.rb 中:

    # 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

以及创建了一个 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
作者头像

我有同样的问题。它与Rails 7.0的兼容性和设计4.8.1的兼容性相关。我无法注册用户。SQLITE3数据库也保持空,因此我不仅仅是闪存消息的问题,并且没有输入用户。有些人通过将以下内容添加到 config/initializers/devise.rb

config.navigational_formats = ['*/*', :html, :turbo_stream]
作者头像

按照这个 link 解决方法。

1.创建一个控制器来响应html和turbo_stream
2.修改config/initializers/devise.rb

作者头像

如果您只是想让它“工作”,您可以将 data: { turbo: false } 添加到您的设计表单中。这将防止 turbo 自动劫持您的表单提交。

此处归功于 john-999 https://github.com/heartcombo/devise/issues/5446#issuecomment-1083485163

就我而言,我的 views/devise/sessions/new.html.erb 看起来像:

    <%= 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 %>
作者头像

我认为最好的答案是 Alex Flash is not displayed in the same view in Rails

再次由 Alex Rails 7 signup form doesn't show error messages

没有设计也是如此,错误消息数组属于 Active Record 并与 Active Record @user 对象相关联,该对象在继承自 ApplicationRecord 和 ActiveRecord 的模型中验证失败,而不是设计。即使您从头开始创建用户模型、控制器、视图和所有操作,当模型中的验证失败时,错误消息仍然会出现,但不会显示在视图中。连闪信都没有显示。相反,如果用户无法保存,则在您的控制器中,然后,在 else 语句中重定向到请求引用者,并在创建用户方法或更新中使用 flash 错误消息(可能类似于 redirect_to request.referrer, flash: {error: @user.errors.full_messages} ),但错误消息似乎没有显示除非服务器以 422 响应,否则您是否正在渲染回新操作,因此您可以像脚手架 render 'new', status: :unprocessable_entity, flash: {error: @user.errors.full_messages} 一样执行相同的操作,这会导致服务器响应为 422,这将起作用。如果@user 保存在数据库中,这也适用于成功消息。或更新你可以只显示 redirect_to user_url(@user), notice: " user was successfully created / updated."

您会在浏览器控制台中注意到,如果您使用无效字段注册,您将不会收到错误 full_messages,并且您会注意到您的浏览器控制台显示: Error: Form responses must redirect to another location ,如果您正在渲染回新操作,如果该对象无法保存在您的创建操作中。

似乎如果您转到 application.html.erb 并删除 <%= javascript_importmap_tags %> ,保存文件并尝试使用无效字段注册,您将获得所有 @user.errors.full_messsages 键和值。不是解决方案。

或者最好不要理会 javascript_importmap_tags,您可以在 data: { turbo: false } 中添加 form_with 。但仍然不是一个可持续的解决方案。

或者像其他人建议的那样,如果您使用设计在 initializers.rb 中注册用户,您可以添加 config.navigational_formats = ['*/*', :html, :turbo_stream]