You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Devise Invitable适配Rails7的Devise turbo_stream导航格式配置?

解决Devise Invitable适配Turbo Stream的问题

问题根源

当Devise的navigational_formats包含:turbo_stream时,Devise Invitable的控制器在处理表单提交后,会默认尝试重定向到users_url(用户列表页),如果路由里没配置这个路径就会报错;就算加上resources :users,控制器在turbo响应下的逻辑又会触发empty?调用的错误——本质是Devise Invitable的默认逻辑没适配Turbo的响应格式。

方案一:自定义邀请控制器适配Turbo Stream

这是最灵活的解决方式,能完全控制turbo响应:

  • 生成自定义的用户邀请控制器:
    rails generate devise:controllers users -c invitations
    
  • 打开app/controllers/users/invitations_controller.rb,重写create方法,专门处理turbo_stream格式的响应:
    class Users::InvitationsController < Devise::InvitationsController
      def create
        super do |resource|
          # 邀请成功且请求是turbo格式时,返回自定义turbo响应
          if resource.errors.empty? && request.format.turbo_stream?
            respond_to do |format|
              format.turbo_stream do
                # 示例:添加成功提示到页面,同时重置表单
                render turbo_stream: [
                  turbo_stream.append('flash_notices', partial: 'shared/flash', locals: { message: '邀请已发送' }),
                  turbo_stream.replace('invitation_form', partial: 'devise/invitations/new', locals: { resource: User.new })
                ]
              end
            end
          end
        end
      end
    
      # 可选:重写update方法,处理用户接受邀请后的turbo响应
      def update
        super do |resource|
          if resource.errors.empty? && request.format.turbo_stream?
            respond_to do |format|
              format.turbo_stream do
                render turbo_stream: turbo_stream.replace('invitation_form', partial: 'users/invitation_success')
              end
            end
          end
        end
      end
    
  • 在config/routes.rb中指定使用这个自定义控制器:
    devise_for :users, controllers: { invitations: 'users/invitations' }
    

方案二:单独给特定Devise控制器开启Turbo支持

如果不想自定义控制器,可以修改initializers/devise.rb,只给需要Turbo的Devise控制器(比如登录、注册)开启turbo_stream格式,邀请控制器保持默认:

# 先把全局navigational_formats改回默认(去掉:turbo_stream)
config.navigational_formats = ['*/*', :html]

# 单独给需要Turbo的Devise控制器添加turbo_stream支持
Rails.application.config.to_prepare do
  Devise::SessionsController.navigational_formats = ['*/*', :html, :turbo_stream]
  Devise::RegistrationsController.navigational_formats = ['*/*', :html, :turbo_stream]
  # 其他需要Turbo的Devise控制器(比如密码重置)也可以在这里添加
end

方案三:修复路由并调整默认跳转路径

如果坚持全局开启Turbo格式,可以:

  • 在config/routes.rb中添加用户列表路由(解决users_url报错):
    resources :users, only: [:index]
    
  • 然后自定义邀请成功后的跳转路径,避免默认跳转到用户列表,同时处理turbo响应:
    class Users::InvitationsController < Devise::InvitationsController
      private
    
      # 重写邀请成功后的跳转路径
      def after_invite_path_for(resource)
        # 改成你实际需要的页面,比如后台首页
        admin_dashboard_path
      end
    
      def create
        build_resource
        resource.invite!(current_inviter) do |err|
          if err
            respond_with_navigational(resource) { render :new }
          else
            set_flash_message! :notice, :send_instructions
            # turbo格式下返回turbo响应,不使用重定向
            if request.format.turbo_stream?
              render turbo_stream: turbo_stream.append('flash', partial: 'shared/flash', locals: { message: flash[:notice] })
            else
              respond_with resource, location: after_invite_path_for(resource)
            end
          end
        end
      end
    end
    
  • 别忘了在路由里指定这个自定义控制器。

内容的提问来源于stack exchange,提问作者don_Bigote

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 07:37:53