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

升级至Rails 7.0.4后出现undefined method `unloadable'错误求助

Rails 7.0.4 升级后 websocket-rails 启动报错修复指南

问题场景

现有继承自WebsocketRails::BaseController的控制器代码:

class SocketController < WebsocketRails::BaseController
  before_action :authenticate_user!
end

将Rails版本升级至7.0.4后,执行rails s启动服务时触发如下错误:

Failure/Error:
  class SocketController < WebsocketRails::BaseController
    before_action :authenticate_user!

NoMethodError:
  undefined method `unloadable' for WebsocketRails::BaseController:Class

          unloadable controller
          ^^^^^^^^^^
# ./vendor/bundle/ruby/3.1.0/gems/websocket-rails-0.7.0/lib/websocket_rails/base_controller.rb:45:in `inherited'
# ./app/controllers/socket_controller.rb:1:in `<top (required)>'
# ./vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.6.6/lib/zeitwerk/kernel.rb:30:in `require'
# ./vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.6.6/lib/zeitwerk/kernel.rb:30:in `require'
# ./vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.6.6/lib/zeitwerk/loader/helpers.rb:135:in `const_get'
# ./vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.6.6/lib/zeitwerk/loader/helpers.rb:135:in `cget'
# ./vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.6.6/lib/zeitwerk/loader/eager_load.rb:169:in `block in actual_eager_load_dir'
# ./vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.6.6/lib/zeitwerk/loader/helpers.rb:40:in `block in ls'
# ./vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.6.6/lib/zeitwerk/loader/helpers.rb:25:in `each'
# ./vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.6.6/lib/zeitwerk/loader/helpers.rb:25:in `ls'
# ./vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.6.6/lib/zeitwerk/loader/eager_load.rb:164:in `actual_eager_load_dir'
# ./vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.6.6/lib/zeitwerk/loader/eager_load.rb:17:in `block (2 levels) in eager_load'
# ./vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.6.6/lib/zeitwerk/loader/eager_load.rb:16:in `each'
# ./vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.6.6/lib/zeitwerk/loader/eager_load.rb:16:in `block in eager_load'
# ./vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.6.6/lib/zeitwerk/loader/eager_load.rb:10:in `synchronize'
# ./vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.6.6/lib/zeitwerk/loader/eager_load.rb:10:in `eager_load'
# ./vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.6.6/lib/zeitwerk/loader.rb:296:in `block in eager_load_all'
# ./vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.6.6/lib/zeitwerk/loader.rb:294:in `each'
# ./vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.6.6/lib/zeitwerk/loader.rb:294:in `eager_load_all'
# ./vendor/bundle/ruby/3.1.0/gems/railties-7.0.4/lib/rails/application/finisher.rb:74:in `block in <module:Finisher>'
# ./vendor/bundle/ruby/3.1.0/gems/railties-7.0.4/lib/rails/initializable.rb:32:in `instance_exec'
# ./vendor/bundle/ruby/3.1.0/gems/railties-7.0.4/lib/rails/initializable.rb:32:in `run'
# ./vendor/bundle/ruby/3.1.0/gems/railties-7.0.4/lib/rails/initializable.rb:61:in `block in run_initializers'
# ./vendor/bundle/ruby/3.1.0/gems/railties-7.0.4/lib/rails/initializable.rb:60:in `run_initializers'
# ./vendor/bundle/ruby/3.1.0/gems/railties-7.0.4/lib/rails/application.rb:372:in `initialize!'
# ./config/environment.rb:5:in `<top (required)>'

问题原因

websocket-rails 0.7.0版本的代码中,WebsocketRails::BaseController的inherited方法调用了Rails旧版本的unloadable方法,但Rails 7.0+默认使用Zeitwerk作为代码加载器,已经移除了unloadable这个方法,导致调用时报错。

修复方案

方案1:给websocket-rails打补丁

在项目的config/initializers目录下新建websocket_rails_patch.rb文件,添加以下代码,手动实现unloadable方法:

module WebsocketRails
  class BaseController
    def self.unloadable(_controller = nil)
      # 空实现,适配Rails7的Zeitwerk加载机制
    end
  end
end

保存后重启服务即可解决报错。

方案2:迁移到官方ActionCable

websocket-rails已经多年未更新,后续可能会出现更多兼容性问题。Rails 7默认集成的ActionCable是官方维护的WebSocket解决方案,稳定性和兼容性更好。迁移步骤大致如下:

  • 移除Gemfile中的websocket-rails(Rails7默认已包含ActionCable,无需手动添加)
  • 将原SocketController的逻辑迁移到ActionCable的Channel中
  • 调整前端WebSocket连接代码,适配ActionCable的连接方式

方案3:临时降级Rails版本

如果暂时无法迁移或打补丁,可以将Rails版本降级到websocket-rails支持的版本(比如Rails 6.x),修改Gemfile中的Rails版本后执行bundle install,但这只是临时方案,不推荐长期使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 20:15:34