Class: SorbetRails::ModelPlugins::ActiveRecordEnum

Inherits:
Base
  • Object
show all
Defined in:
lib/sorbet-rails/model_plugins/active_record_enum.rb

Constant Summary

Constants inherited from Base

Base::Parameter

Instance Attribute Summary

Attributes inherited from Base

#available_classes, #model_class

Instance Method Summary collapse

Methods inherited from Base

#initialize

Methods included from SorbetRails::ModelUtils

#add_relation_query_method, #exists_class_method?, #exists_instance_method?, #model_assoc_proxy_class_name, #model_assoc_relation_class_name, #model_class, #model_class_name, #model_module_name, #model_relation_class_name, #model_relation_type_alias, #model_relation_type_class_name

Constructor Details

This class inherits a constructor from SorbetRails::ModelPlugins::Base

Instance Method Details

#generate(root) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/sorbet-rails/model_plugins/active_record_enum.rb', line 7

def generate(root)
  return unless model_class.defined_enums.size > 0

  enum_module_name = model_module_name("EnumInstanceMethods")
  enum_module_rbi = root.create_module(enum_module_name)
  enum_module_rbi.create_extend("T::Sig")

  model_class_rbi = root.create_class(self.model_class_name)
  model_class_rbi.create_include(enum_module_name)

  # TODO: add any method for signature verification?
  model_class.defined_enums.sort.each do |enum_name, enum_hash|
    value_type = enum_hash.values.map { |v| v.is_a?(Integer) ? 'Integer' : v.class.name }.uniq

    return_type = if value_type.length == 1
      "T::Hash[T.any(String, Symbol), #{value_type.first}]"
    else
      "T::Hash[T.any(String, Symbol), T.any(#{value_type.join(", ")})]"
    end

    model_class_rbi.create_method(
      enum_name.pluralize,
      return_type: return_type,
      class_method: true,
    )

    enum_call = ActiveRecordOverrides.instance.get_enum_call(@model_class, enum_name.to_sym)
    if enum_call.nil?
      puts "Error: unable to find enum call for enum #{enum_name}, model #{self.model_class_name}"
      next
    end

    enum_prefix = enum_call[:_prefix]
    prefix =
      if enum_prefix == true
        "#{enum_name}_"
      elsif enum_prefix
        "#{enum_prefix}_"
      else
        ''
      end
    enum_suffix = enum_call[:_suffix]
    suffix =
      if enum_suffix == true
        "_#{enum_name}"
      elsif enum_suffix
        "_#{enum_suffix}"
      else
        ''
      end

    enum_hash.keys.each do |enum_val|
      next unless SorbetRails::Utils.valid_method_name?(enum_val.to_s)
      enum_module_rbi.create_method(
        "#{prefix}#{enum_val}#{suffix}?",
        return_type: "T::Boolean",
      )
      enum_module_rbi.create_method(
        "#{prefix}#{enum_val}#{suffix}!",
        return_type: nil, # void
      )
    end
  end
end