1

我正在使用 ActiveModel 来验证我的 Ruby on Rails 中的一些表单对象。一个简化的可重现示例如下所示:

# typed: true

class Form
  include ActiveModel::Model
  
  # ...

  validates :name, presence: true
end

问题是,Sorbet 抱怨说validates在 上不存在T.class_of(Form)。即使为ActiveModel::Model模块正确生成了 RBI 文件。

4

1 回答 1

1

您收到此错误的原因是因为 Sorbet 很难理解其原理ActiveSupport::Concern

这里发生的是,当include ActiveModel::Model被调用时,它包括ActiveModel::Validations. 但是由于两者ActiveModel::ModelActiveModel::Validations都是关注点,所以两者ActiveModel::Model::ClassMethods ActiveModel::Validations::ClassMethods被添加到Formusing 中extend。它ActiveModel::Validations::ClassMethods提供了validates方法,而这extend正是 Sorbet 无法静态看到的。

首先,基本srb工具不知道ActiveSupport::Concern也不会产生适当的mixes_in_class_methods调用来让 Sorbet 意识到ClassMethods也在起作用的那些。此外,即使生成了它,它也只会在包含的一个级别上应用,并且在这种情况下会失败。

解决方法是显式添加extend ActiveModel::Validations::ClassMethodsin Form,但这很难看。

最好的解决方案是切换到 Tapioca 工具以生成适当的 RBI 输出来解决问题。我们也将很快开始为这样的嵌套关注点生成解决方案,它应该可以正确解决这个问题。

于 2021-05-17T23:22:35.707 回答