Как сгенерировать файл .RBI для класса ActiveModel

У меня есть PORO, который я использую в качестве объекта-значения. Я добавляю ActiveModel через include ActiveModel::Model для всех тонкостей, которые мне это приносит. Проблема в том, что я не могу понять, как сгенерировать для него файлы RBI, чтобы он проходил srb tc

В настоящее время я использую sorbet-rails, и, поскольку это PORO и не наследуется от ActiveRecord, bundle exec rails_rbi:all или bundle exec rails_rbi:models не будет генерировать файлы .rbi для этого, даже если я помещу его в каталог моделей (в котором он не должен жить).

Я мог бы написать файлы .rbi вручную, но я действительно не хочу этого делать. Есть ли способ, которым я могу автоматически генерировать их?

Вот сокращенный пример модуля, для которого мне нужен файл RBI.

module MyModule
  class MyClass
    include ActiveModel::Model
    extend T::Sig

    VALID_VARIANTS = T.let(['Enum1', 'Enum2'], T::Array[String])

    sig { returns(String) }
    attr_accessor :variant

    validates :variant, presence: true, inclusion: { in: VALID_VARIANTS }
    validate :enum_1_is_valid, if: Proc.new { |a| a.variant == 'Enum1' }

    private

    sig { void }
    def enum_1_is_valid
      # ...
    end
  end
end

person xcskier56    schedule 15.09.2020    source источник
comment
Что вызывает у вас проблему? Вышеприведенный код выглядит прекрасно, за исключением определения методов из ActiveModel::Model.   -  person paracycle    schedule 15.09.2020


Ответы (2)


Проблема в том, что sorbet-typed не включает ActiveModel::Model, который является просто оболочкой вокруг ActiveModel::Validations и некоторых других. При переключении на использование только ActiveModel::Validations код теперь проходит typed: strict.

Основным недостатком этого является то, что мы не получаем хорошего автоматического назначения атрибутов и по-прежнему должны использовать инициализатор. Ничего страшного, но не идеально.

person xcskier56    schedule 16.09.2020

Мой подход к набору ActiveModels следующий.

Я создал базовый класс под названием ApplicationModel.

class ApplicationModel
  extend T::Sig
  include ActiveModel::Model
  include ActiveModel::Validations
  include ActiveModel::Attributes
end

class ExampleModel < ApplicationModel
  attribute :name, :string
end

Затем у меня есть сценарий, который генерирует файлы RBI для подклассов ApplicationModel.

ApplicationModel.subclasses.each do |model|
  # Generate RBI files.
end

Посмотрите, как тапиока генерирует RBI файлы для объектов ActiveRecord, чтобы узнать, как генерировать сигнатуры типов.

person Jeremy B    schedule 12.03.2021