tapioca 0.4.6 → 0.4.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +5 -1
  3. data/README.md +9 -7
  4. data/lib/tapioca/cli.rb +8 -1
  5. data/lib/tapioca/compilers/dsl/action_controller_helpers.rb +38 -39
  6. data/lib/tapioca/compilers/dsl/action_mailer.rb +4 -4
  7. data/lib/tapioca/compilers/dsl/active_record_associations.rb +52 -51
  8. data/lib/tapioca/compilers/dsl/active_record_columns.rb +60 -65
  9. data/lib/tapioca/compilers/dsl/active_record_enum.rb +27 -23
  10. data/lib/tapioca/compilers/dsl/active_record_scope.rb +18 -17
  11. data/lib/tapioca/compilers/dsl/active_record_typed_store.rb +8 -7
  12. data/lib/tapioca/compilers/dsl/active_resource.rb +5 -4
  13. data/lib/tapioca/compilers/dsl/active_support_current_attributes.rb +6 -7
  14. data/lib/tapioca/compilers/dsl/base.rb +14 -10
  15. data/lib/tapioca/compilers/dsl/frozen_record.rb +25 -25
  16. data/lib/tapioca/compilers/dsl/{active_record_identity_cache.rb → identity_cache.rb} +11 -10
  17. data/lib/tapioca/compilers/dsl/protobuf.rb +1 -1
  18. data/lib/tapioca/compilers/dsl/sidekiq_worker.rb +83 -0
  19. data/lib/tapioca/compilers/dsl/smart_properties.rb +1 -1
  20. data/lib/tapioca/compilers/dsl/state_machines.rb +75 -73
  21. data/lib/tapioca/compilers/dsl/url_helpers.rb +9 -5
  22. data/lib/tapioca/compilers/dsl_compiler.rb +5 -5
  23. data/lib/tapioca/compilers/requires_compiler.rb +34 -6
  24. data/lib/tapioca/compilers/sorbet.rb +1 -1
  25. data/lib/tapioca/compilers/symbol_table/symbol_generator.rb +69 -33
  26. data/lib/tapioca/compilers/symbol_table/symbol_loader.rb +1 -1
  27. data/lib/tapioca/compilers/symbol_table_compiler.rb +1 -1
  28. data/lib/tapioca/compilers/todos_compiler.rb +1 -1
  29. data/lib/tapioca/core_ext/class.rb +8 -3
  30. data/lib/tapioca/gemfile.rb +1 -1
  31. data/lib/tapioca/generator.rb +1 -1
  32. data/lib/tapioca/loader.rb +1 -1
  33. data/lib/tapioca/version.rb +1 -1
  34. metadata +4 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dd111409d415b9a17a11cd2d1a5d6d60fdab411934fc5bd1ade87b4bee9e27a3
4
- data.tar.gz: 6cc495adc75090725de7f8cb873672e804452c16931d5a995c543827ab6400cb
3
+ metadata.gz: ade782d63dbf52c361f3275c10366ece6db850a50a056bb6ef6ab73b3d8fe5c1
4
+ data.tar.gz: db41740ac452ad69cecc453cf5fc6ff6ce2634e45ba461670132d386d2a5e938
5
5
  SHA512:
6
- metadata.gz: 993e27b7960ce9830d58098a3a965214342821d87c3753e3b6a72ab8d9d33e86c1a5f454141cd2f19b73565ecfe9f3454c7c7d45825256c27c02ccd2d2396780
7
- data.tar.gz: bfeb2377b5a5b059ce4897cbe1b7e39cef0657d799479ffd75c646897236928cd7fe317fd9cf9a49597b8dd28fc7657e90d9386eb82927cc9cdbb806203c4538
6
+ metadata.gz: ca364aee459f30d35d0b62d4f48ee8bb9977ac458ca4aac74035cf97d2ff6f73571b8d6eb70689d7e389ce7ee67e5f8b7a8ad7773ef9f265c38d41aa030dd76c
7
+ data.tar.gz: 7c67870e40188ad371c33eda3bc44ed92077e451d05100bc7427bd143377763064ae0dad50d02b341ce34ed61ee0e8e3e7ce2b81a4b5b240fb437540cd26dc48
data/Gemfile CHANGED
@@ -15,7 +15,6 @@ gem("yard", "~> 0.9.25")
15
15
  gem("pry-byebug")
16
16
  gem("minitest")
17
17
  gem("minitest-hooks")
18
- gem("minitest-fork_executor")
19
18
  gem("minitest-reporters")
20
19
  gem("sorbet")
21
20
 
@@ -33,4 +32,9 @@ group(:development, :test) do
33
32
  gem("activemodel-serializers-xml", "~> 1.0", require: false)
34
33
  gem("activeresource", "~> 5.1", require: false)
35
34
  gem("google-protobuf", "~>3.12.0", require: false)
35
+ # Fix version to 0.14.1 since it is the last version to support Ruby 2.4
36
+ gem("shopify-money", "= 0.14.1", require: false)
37
+ gem("sidekiq", "~>5.0", require: false) # Version 6 dropped support for Ruby 2.4
36
38
  end
39
+
40
+ gem "rubocop-sorbet", ">= 0.4.1"
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Tapioca
2
2
 
3
- [![Build Status](https://travis-ci.org/Shopify/tapioca.svg?branch=master)](https://travis-ci.org/Shopify/tapioca)
3
+ ![Build Status](https://github.com/Shopify/tapioca/workflows/CI/badge.svg)
4
4
 
5
5
  Tapioca is a library used to generate RBI (Ruby interface) files for use with [Sorbet](https://sorbet.org). RBI files provide the structure (classes, modules, methods, parameters) of the gem/library to Sorbet to assist with typechecking.
6
6
 
@@ -55,6 +55,8 @@ and do not forget to execute `tapioca` using `bundler`:
55
55
  ```shell
56
56
  $ bundle exec tapioca
57
57
  Commands:
58
+ tapioca --version, -v # show version
59
+ tapioca dsl [constant...] # generate RBIs for dynamic methods
58
60
  tapioca generate [gem...] # generate RBIs from gems
59
61
  tapioca help [COMMAND] # Describe available commands or one specific command
60
62
  tapioca init # initializes folder structure
@@ -63,12 +65,12 @@ Commands:
63
65
  tapioca todo # generate the list of unresolved constants
64
66
 
65
67
  Options:
66
- --pre, -b, [--prerequire=file] # A file to be required before Bundler.require is called
67
- --post, -a, [--postrequire=file] # A file to be required after Bundler.require is called
68
- --out, -o, [--outdir=directory] # The output directory for generated RBI files
69
- # Default: sorbet/rbi/gems
70
- --cmd, -c, [--generate-command=command] # The command to run to regenerate RBI files
71
- --typed, -t, [--typed-overrides=gem:level] # Overrides for typed sigils for generated gem RBIs
68
+ --pre, -b, [--prerequire=file] # A file to be required before Bundler.require is called
69
+ --post, -a, [--postrequire=file] # A file to be required after Bundler.require is called
70
+ --out, -o, [--outdir=directory] # The output directory for generated RBI files
71
+ --cmd, -c, [--generate-command=command] # The command to run to regenerate RBI files
72
+ -x, [--exclude=gem [gem ...]] # Excludes the given gem(s) from RBI generation
73
+ --typed, -t, [--typed-overrides=gem:level [gem:level ...]] # Overrides for typed sigils for generated gem RBIs
72
74
  ```
73
75
 
74
76
  ## Usage
@@ -1,5 +1,5 @@
1
- # frozen_string_literal: true
2
1
  # typed: true
2
+ # frozen_string_literal: true
3
3
 
4
4
  require 'thor'
5
5
 
@@ -34,6 +34,8 @@ module Tapioca
34
34
  banner: "gem:level [gem:level ...]",
35
35
  desc: "Overrides for typed sigils for generated gem RBIs"
36
36
 
37
+ map T.unsafe(%w[--version -v] => :__print_version)
38
+
37
39
  desc "init", "initializes folder structure"
38
40
  def init
39
41
  create_file(Config::SORBET_CONFIG, skip: true) do
@@ -92,6 +94,11 @@ module Tapioca
92
94
  end
93
95
  end
94
96
 
97
+ desc "--version, -v", "show version"
98
+ def __print_version
99
+ puts "Tapioca v#{Tapioca::VERSION}"
100
+ end
101
+
95
102
  no_commands do
96
103
  def self.exit_on_failure?
97
104
  true
@@ -13,8 +13,7 @@ module Tapioca
13
13
  module Compilers
14
14
  module Dsl
15
15
  # `Tapioca::Compilers::Dsl::ActionControllerHelpers` decorates RBI files for all
16
- # subclasses of `::ActionController::Base`
17
- # to add helper methods (see https://api.rubyonrails.org/classes/ActionController/Helpers.html).
16
+ # subclasses of [`ActionController::Base`](https://api.rubyonrails.org/classes/ActionController/Helpers.html).
18
17
  #
19
18
  # For example, with the following `MyHelper` module:
20
19
  #
@@ -50,22 +49,22 @@ module Tapioca
50
49
  # # user_controller.rbi
51
50
  # # typed: strong
52
51
  # class UserController
53
- # sig { returns(UserController::HelperProxy) }
54
- # def helpers; end
55
- # end
52
+ # module HelperMethods
53
+ # include MyHelper
56
54
  #
57
- # module UserController::HelperMethods
58
- # include MyHelper
55
+ # sig { params(user: T.untyped).returns(T.untyped) }
56
+ # def age(user); end
59
57
  #
60
- # sig { params(user: T.untyped).returns(T.untyped) }
61
- # def age(user); end
58
+ # sig { returns(T.untyped) }
59
+ # def current_user_name; end
60
+ # end
62
61
  #
63
- # sig { returns(T.untyped) }
64
- # def current_user_name; end
65
- # end
62
+ # class HelperProxy < ::ActionView::Base
63
+ # include HelperMethods
64
+ # end
66
65
  #
67
- # class UserController::HelperProxy < ::ActionView::Base
68
- # include UserController::HelperMethods
66
+ # sig { returns(HelperProxy) }
67
+ # def helpers; end
69
68
  # end
70
69
  # ~~~
71
70
  class ActionControllerHelpers < Base
@@ -77,42 +76,42 @@ module Tapioca
77
76
  .void
78
77
  end
79
78
  def decorate(root, constant)
80
- helper_proxy_name = "#{constant}::HelperProxy"
81
- helper_methods_name = "#{constant}::HelperMethods"
79
+ helper_proxy_name = "HelperProxy"
80
+ helper_methods_name = "HelperMethods"
82
81
  proxied_helper_methods = constant._helper_methods.map(&:to_s).map(&:to_sym)
83
82
 
84
- # Create helper method module
85
- root.create_module(helper_methods_name) do |helper_methods|
86
- helpers_module = constant._helpers
83
+ # Define the helpers method
84
+ root.path(constant) do |controller|
85
+ create_method(controller, 'helpers', return_type: helper_proxy_name)
87
86
 
88
- gather_includes(helpers_module).each do |ancestor|
89
- helper_methods.create_include(ancestor)
90
- end
87
+ # Create helper method module
88
+ controller.create_module(helper_methods_name) do |helper_methods|
89
+ helpers_module = constant._helpers
91
90
 
92
- helpers_module.instance_methods(false).each do |method_name|
93
- method = if proxied_helper_methods.include?(method_name)
94
- constant.instance_method(method_name)
95
- else
96
- helpers_module.instance_method(method_name)
91
+ gather_includes(helpers_module).each do |ancestor|
92
+ helper_methods.create_include(ancestor)
97
93
  end
98
- create_method_from_def(helper_methods, method)
99
- end
100
- end
101
94
 
102
- # Create helper proxy class
103
- root.create_class(helper_proxy_name, superclass: "::ActionView::Base") do |proxy|
104
- proxy.create_include(helper_methods_name)
105
- end
95
+ helpers_module.instance_methods(false).each do |method_name|
96
+ method = if proxied_helper_methods.include?(method_name)
97
+ constant.instance_method(method_name)
98
+ else
99
+ helpers_module.instance_method(method_name)
100
+ end
101
+ create_method_from_def(helper_methods, method)
102
+ end
103
+ end
106
104
 
107
- # Define the helpers method
108
- root.path(constant) do |controller|
109
- create_method(controller, 'helpers', return_type: helper_proxy_name)
105
+ # Create helper proxy class
106
+ controller.create_class(helper_proxy_name, superclass: "::ActionView::Base") do |proxy|
107
+ proxy.create_include(helper_methods_name)
108
+ end
110
109
  end
111
110
  end
112
111
 
113
112
  sig { override.returns(T::Enumerable[Module]) }
114
113
  def gather_constants
115
- ::ActionController::Base.descendants.reject(&:abstract?)
114
+ ::ActionController::Base.descendants.reject(&:abstract?).select(&:name)
116
115
  end
117
116
 
118
117
  private
@@ -121,7 +120,7 @@ module Tapioca
121
120
  def gather_includes(mod)
122
121
  mod.ancestors
123
122
  .reject { |ancestor| ancestor.is_a?(Class) || ancestor == mod || ancestor.name.nil? }
124
- .map { |ancestor| T.must(ancestor.name) }
123
+ .map { |ancestor| "::#{ancestor.name}" }
125
124
  .reverse
126
125
  end
127
126
  end
@@ -12,8 +12,8 @@ end
12
12
  module Tapioca
13
13
  module Compilers
14
14
  module Dsl
15
- # `Tapioca::Compilers::Dsl::ActionMailer` generates RBI files for subclasses of `ActionMailer::Base`
16
- # (see https://api.rubyonrails.org/classes/ActionMailer/Base.html).
15
+ # `Tapioca::Compilers::Dsl::ActionMailer` generates RBI files for subclasses of
16
+ # [`ActionMailer::Base`](https://api.rubyonrails.org/classes/ActionMailer/Base.html).
17
17
  #
18
18
  # For example, with the following `ActionMailer` subclass:
19
19
  #
@@ -40,12 +40,12 @@ module Tapioca
40
40
 
41
41
  sig { override.params(root: Parlour::RbiGenerator::Namespace, constant: T.class_of(::ActionMailer::Base)).void }
42
42
  def decorate(root, constant)
43
- root.path(constant) do |k|
43
+ root.path(constant) do |mailer|
44
44
  constant.action_methods.to_a.each do |mailer_method|
45
45
  method_def = constant.instance_method(mailer_method)
46
46
  parameters = compile_method_parameters_to_parlour(method_def)
47
47
  create_method(
48
- k,
48
+ mailer,
49
49
  mailer_method,
50
50
  parameters: parameters,
51
51
  return_type: '::ActionMailer::MessageDelivery',
@@ -12,9 +12,9 @@ end
12
12
  module Tapioca
13
13
  module Compilers
14
14
  module Dsl
15
- # `Tapioca::Compilers::Dsl::ActiveRecordAssociations` refines RBI files for subclasses of `ActiveRecord::Base`
16
- # (see https://api.rubyonrails.org/classes/ActiveRecord/Base.html). This generator is only
17
- # responsible for defining the methods that would be created for the association that
15
+ # `Tapioca::Compilers::Dsl::ActiveRecordAssociations` refines RBI files for subclasses of
16
+ # [`ActiveRecord::Base`](https://api.rubyonrails.org/classes/ActiveRecord/Base.html).
17
+ # This generator is only responsible for defining the methods that would be created for the associations that
18
18
  # are defined in the Active Record model.
19
19
  #
20
20
  # For example, with the following model class:
@@ -36,56 +36,56 @@ module Tapioca
36
36
  #
37
37
  # class Post
38
38
  # include Post::GeneratedAssociationMethods
39
- # end
40
39
  #
41
- # module Post::GeneratedAssociationMethods
42
- # sig { returns(T.nilable(::User)) }
43
- # def author; end
40
+ # module Post::GeneratedAssociationMethods
41
+ # sig { returns(T.nilable(::User)) }
42
+ # def author; end
44
43
  #
45
- # sig { params(value: T.nilable(::User)).void }
46
- # def author=(value); end
44
+ # sig { params(value: T.nilable(::User)).void }
45
+ # def author=(value); end
47
46
  #
48
- # sig { params(args: T.untyped, blk: T.untyped).returns(T.nilable(::User)) }
49
- # def build_author(*args, &blk); end
47
+ # sig { params(args: T.untyped, blk: T.untyped).returns(::User) }
48
+ # def build_author(*args, &blk); end
50
49
  #
51
- # sig { params(args: T.untyped, blk: T.untyped).returns(T.nilable(::Category)) }
52
- # def build_category(*args, &blk); end
50
+ # sig { params(args: T.untyped, blk: T.untyped).returns(::Category) }
51
+ # def build_category(*args, &blk); end
53
52
  #
54
- # sig { returns(T.nilable(::Category)) }
55
- # def category; end
53
+ # sig { returns(T.nilable(::Category)) }
54
+ # def category; end
56
55
  #
57
- # sig { params(value: T.nilable(::Category)).void }
58
- # def category=(value); end
56
+ # sig { params(value: T.nilable(::Category)).void }
57
+ # def category=(value); end
59
58
  #
60
- # sig { returns(T::Array[T.untyped]) }
61
- # def comment_ids; end
59
+ # sig { returns(T::Array[T.untyped]) }
60
+ # def comment_ids; end
62
61
  #
63
- # sig { params(ids: T::Array[T.untyped]).returns(T::Array[T.untyped]) }
64
- # def comment_ids=(ids); end
62
+ # sig { params(ids: T::Array[T.untyped]).returns(T::Array[T.untyped]) }
63
+ # def comment_ids=(ids); end
65
64
  #
66
- # sig { returns(::ActiveRecord::Associations::CollectionProxy[Comment]) }
67
- # def comments; end
65
+ # sig { returns(::ActiveRecord::Associations::CollectionProxy[Comment]) }
66
+ # def comments; end
68
67
  #
69
- # sig { params(value: T::Enumerable[::Comment]).void }
70
- # def comments=(value); end
68
+ # sig { params(value: T::Enumerable[::Comment]).void }
69
+ # def comments=(value); end
71
70
  #
72
- # sig { params(args: T.untyped, blk: T.untyped).returns(T.nilable(::User)) }
73
- # def create_author(*args, &blk); end
71
+ # sig { params(args: T.untyped, blk: T.untyped).returns(::User) }
72
+ # def create_author(*args, &blk); end
74
73
  #
75
- # sig { params(args: T.untyped, blk: T.untyped).returns(T.nilable(::User)) }
76
- # def create_author!(*args, &blk); end
74
+ # sig { params(args: T.untyped, blk: T.untyped).returns(::User) }
75
+ # def create_author!(*args, &blk); end
77
76
  #
78
- # sig { params(args: T.untyped, blk: T.untyped).returns(T.nilable(::Category)) }
79
- # def create_category(*args, &blk); end
77
+ # sig { params(args: T.untyped, blk: T.untyped).returns(::Category) }
78
+ # def create_category(*args, &blk); end
80
79
  #
81
- # sig { params(args: T.untyped, blk: T.untyped).returns(T.nilable(::Category)) }
82
- # def create_category!(*args, &blk); end
80
+ # sig { params(args: T.untyped, blk: T.untyped).returns(::Category) }
81
+ # def create_category!(*args, &blk); end
83
82
  #
84
- # sig { returns(T.nilable(::User)) }
85
- # def reload_author; end
83
+ # sig { returns(T.nilable(::User)) }
84
+ # def reload_author; end
86
85
  #
87
- # sig { returns(T.nilable(::Category)) }
88
- # def reload_category; end
86
+ # sig { returns(T.nilable(::Category)) }
87
+ # def reload_category; end
88
+ # end
89
89
  # end
90
90
  # ~~~
91
91
  class ActiveRecordAssociations < Base
@@ -99,19 +99,20 @@ module Tapioca
99
99
  def decorate(root, constant)
100
100
  return if constant.reflections.empty?
101
101
 
102
- module_name = "#{constant}::GeneratedAssociationMethods"
103
- root.create_module(module_name) do |mod|
104
- constant.reflections.each do |association_name, reflection|
105
- if reflection.collection?
106
- populate_collection_assoc_getter_setter(mod, constant, association_name, reflection)
107
- else
108
- populate_single_assoc_getter_setter(mod, constant, association_name, reflection)
102
+ root.path(constant) do |model|
103
+ module_name = "GeneratedAssociationMethods"
104
+
105
+ model.create_module(module_name) do |mod|
106
+ constant.reflections.each do |association_name, reflection|
107
+ if reflection.collection?
108
+ populate_collection_assoc_getter_setter(mod, constant, association_name, reflection)
109
+ else
110
+ populate_single_assoc_getter_setter(mod, constant, association_name, reflection)
111
+ end
109
112
  end
110
113
  end
111
- end
112
114
 
113
- root.path(constant) do |klass|
114
- klass.create_include(module_name)
115
+ model.create_include(module_name)
115
116
  end
116
117
  end
117
118
 
@@ -152,7 +153,7 @@ module Tapioca
152
153
  "reload_#{association_name}",
153
154
  return_type: association_type,
154
155
  )
155
- if reflection.constructable?
156
+ unless reflection.polymorphic?
156
157
  create_method(
157
158
  klass,
158
159
  "build_#{association_name}",
@@ -160,7 +161,7 @@ module Tapioca
160
161
  Parlour::RbiGenerator::Parameter.new("*args", type: "T.untyped"),
161
162
  Parlour::RbiGenerator::Parameter.new("&blk", type: "T.untyped"),
162
163
  ],
163
- return_type: association_type
164
+ return_type: association_class
164
165
  )
165
166
  create_method(
166
167
  klass,
@@ -169,7 +170,7 @@ module Tapioca
169
170
  Parlour::RbiGenerator::Parameter.new("*args", type: "T.untyped"),
170
171
  Parlour::RbiGenerator::Parameter.new("&blk", type: "T.untyped"),
171
172
  ],
172
- return_type: association_type
173
+ return_type: association_class
173
174
  )
174
175
  create_method(
175
176
  klass,
@@ -178,7 +179,7 @@ module Tapioca
178
179
  Parlour::RbiGenerator::Parameter.new("*args", type: "T.untyped"),
179
180
  Parlour::RbiGenerator::Parameter.new("&blk", type: "T.untyped"),
180
181
  ],
181
- return_type: association_type
182
+ return_type: association_class
182
183
  )
183
184
  end
184
185
  end
@@ -12,24 +12,12 @@ end
12
12
  module Tapioca
13
13
  module Compilers
14
14
  module Dsl
15
- # `Tapioca::Compilers::Dsl::ActiveRecordColumns` refines RBI files for subclasses of `ActiveRecord::Base`
16
- # (see https://api.rubyonrails.org/classes/ActiveRecord/Base.html). This generator is only
17
- # responsible for defining the attribute methods that would be created for the columns that
18
- # are defined in the Active Record model.
19
- #
20
- # **Note:** This generator, by default, generates weak signatures for column methods and treats each
21
- # column to be `T.untyped`. This is done on purpose to ensure that the nilability of Active Record
22
- # columns do not make it hard for existing code to adopt gradual typing. It is possible, however, to
23
- # generate stricter type signatures for your ActiveRecord column types. If your ActiveRecord model extends
24
- # a module with name `StrongTypeGeneration`, this generator will generate stricter signatures that follow
25
- # closely with the types defined in the schema.
26
- #
27
- # The `StrongTypeGeneration` module you define in your application should add an `after_initialize` callback
28
- # to the model and ensure that all the non-nilable attributes of the model are actually initialized with non-`nil`
29
- # values.
15
+ # `Tapioca::Compilers::Dsl::ActiveRecordColumns` refines RBI files for subclasses of
16
+ # [`ActiveRecord::Base`](https://api.rubyonrails.org/classes/ActiveRecord/Base.html).
17
+ # This generator is only responsible for defining the attribute methods that would be
18
+ # created for the columns that are defined in the Active Record model.
30
19
  #
31
20
  # For example, with the following model class:
32
- #
33
21
  # ~~~rb
34
22
  # class Post < ActiveRecord::Base
35
23
  # end
@@ -54,54 +42,58 @@ module Tapioca
54
42
  # # post.rbi
55
43
  # # typed: true
56
44
  # class Post
57
- # sig { returns(T.nilable(::String)) }
58
- # def body; end
45
+ # include GeneratedAttributeMethods
46
+ #
47
+ # module GeneratedAttributeMethods
48
+ # sig { returns(T.nilable(::String)) }
49
+ # def body; end
59
50
  #
60
- # sig { params(value: T.nilable(::String)).returns(T.nilable(::String)) }
61
- # def body=; end
51
+ # sig { params(value: T.nilable(::String)).returns(T.nilable(::String)) }
52
+ # def body=; end
62
53
  #
63
- # sig { params(args: T.untyped).returns(T::Boolean) }
64
- # def body?; end
54
+ # sig { returns(T::Boolean) }
55
+ # def body?; end
65
56
  #
66
- # sig { returns(T.nilable(::ActiveSupport::TimeWithZone)) }
67
- # def created_at; end
57
+ # sig { returns(T.nilable(::ActiveSupport::TimeWithZone)) }
58
+ # def created_at; end
68
59
  #
69
- # sig { params(value: ::ActiveSupport::TimeWithZone).returns(::ActiveSupport::TimeWithZone) }
70
- # def created_at=; end
60
+ # sig { params(value: ::ActiveSupport::TimeWithZone).returns(::ActiveSupport::TimeWithZone) }
61
+ # def created_at=; end
71
62
  #
72
- # sig { params(args: T.untyped).returns(T::Boolean) }
73
- # def created_at?; end
63
+ # sig { returns(T::Boolean) }
64
+ # def created_at?; end
74
65
  #
75
- # sig { returns(T.nilable(T::Boolean)) }
76
- # def published; end
66
+ # sig { returns(T.nilable(T::Boolean)) }
67
+ # def published; end
77
68
  #
78
- # sig { params(value: T::Boolean).returns(T::Boolean) }
79
- # def published=; end
69
+ # sig { params(value: T::Boolean).returns(T::Boolean) }
70
+ # def published=; end
80
71
  #
81
- # sig { params(args: T.untyped).returns(T::Boolean) }
82
- # def published?; end
72
+ # sig { returns(T::Boolean) }
73
+ # def published?; end
83
74
  #
84
- # sig { returns(::String) }
85
- # def title; end
75
+ # sig { returns(::String) }
76
+ # def title; end
86
77
  #
87
- # sig { params(value: ::String).returns(::String) }
88
- # def title=(value); end
78
+ # sig { params(value: ::String).returns(::String) }
79
+ # def title=(value); end
89
80
  #
90
- # sig { params(args: T.untyped).returns(T::Boolean) }
91
- # def title?(*args); end
81
+ # sig { returns(T::Boolean) }
82
+ # def title?; end
92
83
  #
93
- # sig { returns(T.nilable(::ActiveSupport::TimeWithZone)) }
94
- # def updated_at; end
84
+ # sig { returns(T.nilable(::ActiveSupport::TimeWithZone)) }
85
+ # def updated_at; end
95
86
  #
96
- # sig { params(value: ::ActiveSupport::TimeWithZone).returns(::ActiveSupport::TimeWithZone) }
97
- # def updated_at=; end
87
+ # sig { params(value: ::ActiveSupport::TimeWithZone).returns(::ActiveSupport::TimeWithZone) }
88
+ # def updated_at=; end
98
89
  #
99
- # sig { params(args: T.untyped).returns(T::Boolean) }
100
- # def updated_at?; end
90
+ # sig { returns(T::Boolean) }
91
+ # def updated_at?; end
101
92
  #
102
- # ## Also the methods added by https://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Dirty.html
103
- # ## Also the methods added by https://api.rubyonrails.org/classes/ActiveModel/Dirty.html
104
- # ## Also the methods added by https://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/BeforeTypeCast.html
93
+ # ## Also the methods added by https://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Dirty.html
94
+ # ## Also the methods added by https://api.rubyonrails.org/classes/ActiveModel/Dirty.html
95
+ # ## Also the methods added by https://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/BeforeTypeCast.html
96
+ # end
105
97
  # end
106
98
  # ~~~
107
99
  class ActiveRecordColumns < Base
@@ -111,26 +103,27 @@ module Tapioca
111
103
  def decorate(root, constant)
112
104
  return unless constant.table_exists?
113
105
 
114
- module_name = "#{constant}::GeneratedAttributeMethods"
115
- root.create_module(module_name) do |mod|
116
- constant.columns_hash.each_key do |column_name|
117
- column_name = column_name.to_s
118
- add_methods_for_attribute(mod, constant, column_name)
119
- end
106
+ root.path(constant) do |model|
107
+ module_name = "GeneratedAttributeMethods"
108
+
109
+ model.create_module(module_name) do |mod|
110
+ constant.columns_hash.each_key do |column_name|
111
+ column_name = column_name.to_s
112
+ add_methods_for_attribute(mod, constant, column_name)
113
+ end
120
114
 
121
- constant.attribute_aliases.each do |attribute_name, column_name|
122
- attribute_name = attribute_name.to_s
123
- column_name = column_name.to_s
124
- new_method_names = constant.attribute_method_matchers.map { |m| m.method_name(attribute_name) }
125
- old_method_names = constant.attribute_method_matchers.map { |m| m.method_name(column_name) }
126
- methods_to_add = new_method_names - old_method_names
115
+ constant.attribute_aliases.each do |attribute_name, column_name|
116
+ attribute_name = attribute_name.to_s
117
+ column_name = column_name.to_s
118
+ new_method_names = constant.attribute_method_matchers.map { |m| m.method_name(attribute_name) }
119
+ old_method_names = constant.attribute_method_matchers.map { |m| m.method_name(column_name) }
120
+ methods_to_add = new_method_names - old_method_names
127
121
 
128
- add_methods_for_attribute(mod, constant, column_name, attribute_name, methods_to_add)
122
+ add_methods_for_attribute(mod, constant, column_name, attribute_name, methods_to_add)
123
+ end
129
124
  end
130
- end
131
125
 
132
- root.path(constant) do |klass|
133
- klass.create_include(module_name)
126
+ model.create_include(module_name)
134
127
  end
135
128
  end
136
129
 
@@ -318,6 +311,8 @@ module Tapioca
318
311
 
319
312
  getter_type =
320
313
  case column_type
314
+ when defined?(MoneyColumn) && MoneyColumn::ActiveRecordType
315
+ "::Money"
321
316
  when ActiveRecord::Type::Integer
322
317
  "::Integer"
323
318
  when ActiveRecord::Type::String