Tapioca为Rails模型生成RBI文件时has_many关联触发srb tc报错
问题根因
报错的核心原因是当前你使用的ActiveRecord对应的Sorbet RBI定义中,ActiveRecord::Associations::CollectionProxy没有被声明为泛型类,Sorbet无法识别CollectionProxy[Plan]这类带类型参数的写法,会把方括号误判为对[]方法的调用。
排查步骤
- 确认Tapioca、sorbet-static、sorbet-runtime三个依赖的版本是否匹配,低版本Tapioca生成has_many关联签名时会默认使用泛型写法,但旧版本ActiveRecord的RBI并没有对CollectionProxy做泛型声明。
- 确认项目内是否存在旧的Sorbet自动生成的RBI残留,和Tapioca生成的文件产生冲突。
解决方案
方案1:升级依赖(推荐)
新版本的工具链已经原生兼容该场景,执行以下操作即可:
- 升级相关依赖到匹配版本
bundle update tapioca sorbet sorbet-runtime sorbet-static - 清理旧的DSL RBI文件
rm -rf sorbet/rbi/dsl - 重新生成所有DSL RBI文件
bin/tapioca dsl - 运行
srb tc验证错误是否消失
方案2:关闭泛型关联生成(适配旧版本)
如果暂时无法升级依赖,可以通过Tapioca配置关闭关联的泛型签名生成:
- 在项目根目录打开
tapioca/config.yml,添加如下配置:tapioca: dsl: active_record: generate_association_generic_types: false - 重新执行
bin/tapioca dsl生成RBI,新生成的关联签名会去掉泛型参数,变为returns(::ActiveRecord::Associations::CollectionProxy),不会再触发报错。
方案3:手动添加泛型垫片(临时救急)
如果既不能升级依赖也不想改Tapioca配置,可以手动添加泛型声明垫片:
在sorbet/rbi/shims目录下新建collection_proxy.rbi文件,写入以下内容:
module ActiveRecord module Associations class CollectionProxy extend T::Generic Elem = type_member end end end
Sorbet识别到该声明后即可正常解析CollectionProxy[Plan]的泛型写法。
内容的提问来源于stack exchange,提问作者Peter Nixey
相关产品推荐
相关产品推荐

