包含 ActiveModel::Model 时,Sorbet 找不到 validates 方法
Sorbet can't find `validates` method when including `ActiveModel::Model`
我在 Rails 上使用 ActiveModel 来验证我 Ruby 中的一些表单对象。一个简化的可重现示例如下所示:
# typed: true
class Form
include ActiveModel::Model
# ...
validates :name, presence: true
end
问题是,Sorbet 抱怨 validates
在 T.class_of(Form)
上不存在。即使为 ActiveModel::Model
模块正确生成了 RBI 文件。
您收到此错误的原因是,Sorbet 真的很难理解 ActiveSupport::Concern
的工作机制。
这里发生的事情是,当调用 include ActiveModel::Model
时,它会包含 ActiveModel::Validations
。但是由于 ActiveModel::Model
和 ActiveModel::Validations
都是问题,因此 ActiveModel::Model::ClassMethods
和 ActiveModel::Validations::ClassMethods
都添加到 Form
使用 extend
。是ActiveModel::Validations::ClassMethods
提供了validates
方法,而extend
是Sorbet静态看不到的
首先,基本 srb
工具不了解 ActiveSupport::Concern
并且不会生成适当的 mixes_in_class_methods
调用来让 Sorbet 知道 ClassMethods
也在玩。此外,即使生成了它,它也只会应用于包含的一个级别,并且在这种情况下会失败。
解决方法是在 Form
中显式添加一个 extend ActiveModel::Validations::ClassMethods
,但这很难看。
最好的解决方案是切换到 Tapioca 工具以生成适当的 RBI 输出以解决问题。我们也将很快开始为像这样的嵌套关注点生成一个解决方案,这应该能很好地解决这个问题。
我在 Rails 上使用 ActiveModel 来验证我 Ruby 中的一些表单对象。一个简化的可重现示例如下所示:
# typed: true
class Form
include ActiveModel::Model
# ...
validates :name, presence: true
end
问题是,Sorbet 抱怨 validates
在 T.class_of(Form)
上不存在。即使为 ActiveModel::Model
模块正确生成了 RBI 文件。
您收到此错误的原因是,Sorbet 真的很难理解 ActiveSupport::Concern
的工作机制。
这里发生的事情是,当调用 include ActiveModel::Model
时,它会包含 ActiveModel::Validations
。但是由于 ActiveModel::Model
和 ActiveModel::Validations
都是问题,因此 ActiveModel::Model::ClassMethods
和 ActiveModel::Validations::ClassMethods
都添加到 Form
使用 extend
。是ActiveModel::Validations::ClassMethods
提供了validates
方法,而extend
是Sorbet静态看不到的
首先,基本 srb
工具不了解 ActiveSupport::Concern
并且不会生成适当的 mixes_in_class_methods
调用来让 Sorbet 知道 ClassMethods
也在玩。此外,即使生成了它,它也只会应用于包含的一个级别,并且在这种情况下会失败。
解决方法是在 Form
中显式添加一个 extend ActiveModel::Validations::ClassMethods
,但这很难看。
最好的解决方案是切换到 Tapioca 工具以生成适当的 RBI 输出以解决问题。我们也将很快开始为像这样的嵌套关注点生成一个解决方案,这应该能很好地解决这个问题。