How to Generate .RBI file for an ActiveModel Class

606 Views Asked by At

I have a PORO that I'm using as a value object. I'm adding ActiveModel via include ActiveModel::Model for all of the niceties that that brings me. The problem is that I cannot figure out how to generate RBI files for it so that it will pass srb tc

I'm currently using sorbet-rails and since this is a PORO and does not inherit from ActiveRecord, bundle exec rails_rbi:all or bundle exec rails_rbi:models will not generate .rbi files for this even if I place it in the models dir (which it should not live in).

I could write the .rbi files by hand, but I really don't want to do that. Is there a way that I can auto generate them?

Here is a parred down example of the module I need an RBI file for

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
2

There are 2 best solutions below

0
On BEST ANSWER

The issue is that sorbet-typed does not include ActiveModel::Model which is just a wrapper around ActiveModel::Validations and a few others. By switching to only using ActiveModel::Validations, the code now passes typed: strict.

The main downside to this is we don't get the nice automatic attribute assignment and still need to use an initializer. Not a big deal, but not perfect.

0
On

My approach to typing ActiveModels is as follows.

I created a base class called ApplicationModel.

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

class ExampleModel < ApplicationModel
  attribute :name, :string
end

I then have a script that generates RBI files for subclasses of ApplicationModel.

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

Take a look at how tapioca generates RBI files for ActiveRecord objects for how to generate type signatures.