Class: Tapioca::Dsl::Compilers::MoneyRails

Inherits:
Tapioca::Dsl::Compiler
  • Object
show all
Extended by:
T::Sig
Includes:
RBIHelper
Defined in:
lib/tapioca/dsl/compilers/money_rails.rb

Overview

‘Tapioca::Dsl::Compilers::MoneyRails` decorates RBI files for classes that use the `monetize` method provided by the `money-rails` gem. github.com/RubyMoney/money-rails

For example, with the following ActiveRecord model: ~~~rb class Product < ActiveRecord::Base

monetize :price_cents

end ~~~

This compiler will generate the following RBI: ~~~rbi class Product

include MoneyRailsGeneratedMethods

module MoneyRailsGeneratedMethods
  sig { returns(::Money) }
  def price; end

  sig { params(value: ::Money).returns(::Money) }
  def price=(value); end
end

end ~~~

Constant Summary collapse

ConstantType =
type_member do
  {
    fixed: T.all(
      T.class_of(::MoneyRails::ActiveRecord::Monetizable),
      ::MoneyRails::ActiveRecord::Monetizable::ClassMethods,
    ),
  }
end
ColumnTypeOption =
Tapioca::Dsl::Helpers::ActiveRecordColumnTypeHelper::ColumnTypeOption

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.gather_constantsObject



55
56
57
# File 'lib/tapioca/dsl/compilers/money_rails.rb', line 55

def gather_constants
  all_classes.select { |c| c < ::MoneyRails::ActiveRecord::Monetizable }
end

Instance Method Details

#column_type_optionObject



63
64
65
66
67
68
69
70
71
72
73
# File 'lib/tapioca/dsl/compilers/money_rails.rb', line 63

def column_type_option
  @column_type_option ||= T.let(
    ColumnTypeOption.from_options(options) do |value, default_column_type_option|
      add_error(<<~MSG.strip)
        Unknown value for compiler option `ActiveRecordColumnTypes` given: `#{value}`.
        Proceeding with the default value: `#{default_column_type_option.serialize}`.
      MSG
    end,
    T.nilable(ColumnTypeOption),
  )
end

#decorateObject



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/tapioca/dsl/compilers/money_rails.rb', line 76

def decorate
  return if constant.monetized_attributes.empty?

  root.create_path(constant) do |klass|
    instance_module_name = "MoneyRailsGeneratedMethods"
    instance_module = RBI::Module.new(instance_module_name)

    constant.monetized_attributes.each do |attribute_name, column_name|
      if column_type_option.untyped?
        type_name = "T.untyped"
      else
        type_name = "::Money"

        nilable_attribute = if constant < ::ActiveRecord::Base && column_type_option.persisted?
          Boba::ActiveRecord::AttributeService.nilable_attribute?(
            T.cast(constant, T.class_of(::ActiveRecord::Base)),
            attribute_name,
            column_name: column_name,
          )
        else
          true
        end

        type_name = as_nilable_type(type_name) if nilable_attribute
      end

      # Model: monetize :amount_cents
      # => amount
      # => amount=
      instance_module.create_method(attribute_name, return_type: type_name)
      instance_module.create_method(
        "#{attribute_name}=",
        parameters: [create_param("value", type: type_name)],
        return_type: type_name,
      )
    end

    klass << instance_module
    klass.create_include(instance_module_name)
  end
end