如何在不使用sorbet-rails的情况下为Rails 7应用配置Sorbet?
在不使用sorbet-rails的情况下为Rails 7应用配置Sorbet
问题场景
现有标准Rails 7应用,希望接入Sorbet但不想使用sorbet-rails,按Sorbet官方指引完成以下操作后遇到类型检查错误:
- 在Gemfile中添加依赖并执行
bundle install:
gem 'sorbet', :group => :development gem 'sorbet-runtime' gem 'tapioca', require: false, :group => :development
- 执行一系列Tapioca初始化命令:
bundle exec tapioca init bin/tapioca dsl bin/tapioca gem bin/tapioca require bin/tapioca gem --all bin/tapioca annotations
首次运行bundle exec srb tc时出现约23个错误,多与生成的RBI文件相关,示例错误:
sorbet/rbi/dsl/sessions_controller.rbi:19: Unable to resolve constant ActionHelper 19 | include ::Turbo::Streams::ActionHelper ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
应用Turbo相关错误的解决方案后,仍存在3个与permit方法相关的错误:
app/controllers/people_controller.rb:48: Method permit does not exist on String component of T.any(String, Numeric, T::Array[T.untyped], ActionController::Parameters) 48 | params.require(:person).permit( ^^^^^^
询问是否存在遗漏步骤,以及正确的配置方式。
解决方案与正确配置步骤
1. 解决Turbo相关的RBI文件错误
针对Turbo::Streams::ActionHelper无法解析的问题,可通过手动补充RBI定义来修复:
- 在
sorbet/rbi/shims目录下创建turbo.rbi文件 - 添加以下内容:
module Turbo module Streams module ActionHelper; end end end
- 重新运行
bin/tapioca dsl和srb tc验证错误是否消除
2. 解决permit方法的类型错误
针对params.require返回值类型不明确导致的permit方法不存在错误,可通过以下两种方式修复:
方式一:添加类型断言
在调用permit前,显式断言返回值为ActionController::Parameters:
params.require(:person).tap { |p| T.assert_type!(p, ActionController::Parameters) }.permit( # 允许的参数列表 )
方式二:自定义params的类型签名
在sorbet/rbi/shims目录下创建action_controller_parameters.rbi文件,补充require方法的精确类型:
class ActionController::Parameters sig { |key: String| returns(ActionController::Parameters) } def require(key); end end
- 重新运行
srb tc验证错误是否消除
完整的正确配置流程
- 添加Gem依赖并执行
bundle install - 运行
bundle exec tapioca init生成基础配置 - 运行
bin/tapioca gem --all生成所有gem的RBI文件 - 运行
bin/tapioca dsl生成DSL相关的RBI文件 - 运行
bin/tapioca require生成require相关的RBI文件 - 运行
bin/tapioca annotations生成注释相关的RBI文件 - 针对Turbo和
permit方法的问题,添加对应的shim RBI文件 - 运行
bundle exec srb tc进行类型检查,根据剩余错误补充必要的类型定义或断言
内容的提问来源于stack exchange,提问作者Vinicius Rocha
相关产品推荐
相关产品推荐

