class Tapioca::Dsl::Compilers::ActiveRecordDelegatedTypes

: [ConstantType = (singleton(ActiveRecord::Base) & Extensions::ActiveRecord)]
~~~
end
end
def comment_id; end
sig { returns(T.nilable(Integer)) }
def comment; end
sig { returns(T.nilable(Comment)) }
def comment?; end
sig { returns(T::Boolean) }
def message_id; end
sig { returns(T.nilable(Integer)) }
def message; end
sig { returns(T.nilable(Message)) }
def message?; end
sig { returns(T::Boolean) }
def entryable_name; end
sig { returns(ActiveSupport::StringInquirer) }
def entryable_class; end
sig { returns(Class) }
def build_entryable(*args); end
sig { params(args: T.untyped).returns(T.any(Message, Comment)) }
module GeneratedDelegatedTypeMethods
include GeneratedDelegatedTypeMethods
class Entry
# typed: true
# entry.rbi
~~~rbi
`entry.rbi`:
this compiler will produce the following methods in the RBI file
~~~
end
delegated_type :entryable, types: %w[ Message Comment ]
class Entry < ActiveRecord::Base
~~~rb
For example, with the following model class:
are defined in the Active Record model.
This compiler is only responsible for defining the methods that would be created for delegated_types that<br>(api.rubyonrails.org/classes/ActiveRecord/Base.html).
‘Tapioca::Dsl::Compilers::DelegatedTypes` defines RBI files for subclasses of

def decorate

: -> void
@override
def decorate
  return if constant.__tapioca_delegated_types.nil?
  root.create_path(constant) do |model|
    model.create_module(DelegatedTypesModuleName) do |mod|
      constant.__tapioca_delegated_types.each do |role, data|
        types = data.fetch(:types)
        options = data.fetch(:options, {})
        populate_role_accessors(mod, role, types)
        populate_type_helpers(mod, role, types, options)
      end
    end
    model.create_include(DelegatedTypesModuleName)
  end
end

def gather_constants

: -> T::Enumerable[Module]
@override
def gather_constants
  descendants_of(::ActiveRecord::Base).reject(&:abstract_class?)
end

def populate_role_accessors(mod, role, types)

: (RBI::Scope mod, Symbol role, Array[String] types) -> void
def populate_role_accessors(mod, role, types)
  mod.create_method(
    "#{role}_name",
    parameters: [],
    return_type: "ActiveSupport::StringInquirer",
  )
  mod.create_method(
    "#{role}_class",
    parameters: [],
    return_type: "T::Class[T.anything]",
  )
  mod.create_method(
    "build_#{role}",
    parameters: [create_rest_param("args", type: "T.untyped")],
    return_type: "T.any(#{types.join(", ")})",
  )
end

def populate_type_helper(mod, role, type, options)

: (RBI::Scope mod, Symbol role, String type, Hash[Symbol, untyped] options) -> void
def populate_type_helper(mod, role, type, options)
  singular   = type.tableize.tr("/", "_").singularize
  query      = "#{singular}?"
  primary_key = options[:primary_key] || "id"
  role_id = options[:foreign_key] || "#{role}_id"
  getter_type, _ = Helpers::ActiveRecordColumnTypeHelper.new(constant).type_for(role_id.to_s)
  mod.create_method(
    query,
    parameters: [],
    return_type: "T::Boolean",
  )
  mod.create_method(
    singular,
    parameters: [],
    return_type: "T.nilable(#{type})",
  )
  mod.create_method(
    "#{singular}_#{primary_key}",
    parameters: [],
    return_type: as_nilable_type(getter_type),
  )
end

def populate_type_helpers(mod, role, types, options)

: (RBI::Scope mod, Symbol role, Array[String] types, Hash[Symbol, untyped] options) -> void
def populate_type_helpers(mod, role, types, options)
  types.each do |type|
    populate_type_helper(mod, role, type, options)
  end
end