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

Rails控制器引用Sorbet类型触发NameError问题求助

问题原因与解决方案

问题原因

1. 命名空间与目录结构不匹配

Rails自动加载遵循「目录对应模块层级」的约定:如果你的类型常量是Types::Services::Session::UserSignUpParamsType,但文件存放在app/sorbet_types/services/session/user_sign_up_params_type.rb,Rails会默认把这个路径映射为Services::Session::UserSignUpParamsType,而非带Types前缀的命名空间。这种不匹配导致Rails无法通过常量名定位到对应的类型文件。

2. 加载时机差异

控制器在Rails启动阶段就会被预加载(尤其是生产环境的eager load模式),但app/sorbet_types可能未被加入eager load路径,导致类型文件在控制器加载时还未被加载。而services目录的文件是按需加载的,当服务被调用时,类型文件可能已经通过其他请求或依赖加载完成,所以不会触发错误。

3. Sorbet与Rails自动加载的冲突

在Sorbet的typed: strict或typed: strong模式下,静态检查阶段会解析常量,但如果Rails的自动加载还未加载对应文件,就会触发运行时的NameError。

解决方案

方案1:修正命名空间与目录结构(推荐)

严格遵循Rails自动加载约定,二选一调整:

  • 保留Types前缀命名空间:将类型文件移动到app/sorbet_types/types/services/session/user_sign_up_params_type.rb,文件内模块定义保持不变:
    # app/sorbet_types/types/services/session/user_sign_up_params_type.rb
    module Types
      module Services
        module Session
          class UserSignUpParamsType
            # 类型定义代码
          end
        end
      end
    end
    
  • 简化命名空间:将类型文件留在原路径,把常量改为Services::Session::UserSignUpParamsType,同时在控制器和services中统一使用这个命名。

方案2:配置自动加载与预加载路径

在config/application.rb中把app/sorbet_types加入autoload和eager load路径,确保所有环境下类型文件能被正确加载:

# config/application.rb
config.autoload_paths << Rails.root.join('app/sorbet_types')
config.eager_load_paths << Rails.root.join('app/sorbet_types')

开发环境下如果不想全局开启eager load,可以在控制器顶部用require_dependency替代require_relative,让Rails管理加载:

# 控制器文件顶部
require_dependency 'types/services/session/user_sign_up_params_type'

方案3:用Sorbet指令手动映射常量

在类型文件顶层添加Sorbet的autoload指令,明确常量与文件的对应关系:

# app/sorbet_types/services/session/user_sign_up_params_type.rb
# typed: true
module Types
  module Services
    module Session
      autoload :UserSignUpParamsType, __FILE__
      class UserSignUpParamsType
        # 类型定义代码
      end
    end
  end
end

也可以在sig/config.rb中全局配置常量映射:

# sig/config.rb
autoload_constant('Types::Services::Session::UserSignUpParamsType', 'app/sorbet_types/services/session/user_sign_up_params_type.rb')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 02:00:17