tapioca 0.10.4 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/lib/tapioca/cli.rb +14 -5
  3. data/lib/tapioca/commands/annotations.rb +2 -0
  4. data/lib/tapioca/commands/configure.rb +1 -0
  5. data/lib/tapioca/commands/dsl.rb +17 -3
  6. data/lib/tapioca/commands/gem.rb +4 -2
  7. data/lib/tapioca/dsl/compilers/aasm.rb +78 -17
  8. data/lib/tapioca/dsl/compilers/action_controller_helpers.rb +1 -1
  9. data/lib/tapioca/dsl/compilers/active_record_columns.rb +3 -3
  10. data/lib/tapioca/dsl/compilers/active_record_fixtures.rb +8 -5
  11. data/lib/tapioca/dsl/compilers/active_record_relations.rb +140 -83
  12. data/lib/tapioca/dsl/compilers/active_record_scope.rb +1 -1
  13. data/lib/tapioca/dsl/compilers/active_record_secure_token.rb +74 -0
  14. data/lib/tapioca/dsl/compilers/active_record_typed_store.rb +14 -11
  15. data/lib/tapioca/dsl/compilers/active_resource.rb +22 -15
  16. data/lib/tapioca/dsl/compilers/active_storage.rb +4 -2
  17. data/lib/tapioca/dsl/compilers/graphql_input_object.rb +21 -1
  18. data/lib/tapioca/dsl/compilers/kredis.rb +130 -0
  19. data/lib/tapioca/dsl/compilers/smart_properties.rb +7 -4
  20. data/lib/tapioca/dsl/compilers/url_helpers.rb +7 -4
  21. data/lib/tapioca/dsl/extensions/active_record.rb +9 -0
  22. data/lib/tapioca/dsl/extensions/kredis.rb +114 -0
  23. data/lib/tapioca/dsl/helpers/active_record_column_type_helper.rb +37 -27
  24. data/lib/tapioca/dsl/helpers/active_record_constants_helper.rb +1 -0
  25. data/lib/tapioca/dsl/pipeline.rb +12 -5
  26. data/lib/tapioca/gem/listeners/sorbet_enums.rb +1 -1
  27. data/lib/tapioca/gem/listeners/yard_doc.rb +13 -10
  28. data/lib/tapioca/gem/pipeline.rb +14 -0
  29. data/lib/tapioca/gemfile.rb +6 -2
  30. data/lib/tapioca/helpers/rbi_files_helper.rb +12 -6
  31. data/lib/tapioca/helpers/sorbet_helper.rb +7 -4
  32. data/lib/tapioca/helpers/source_uri.rb +10 -7
  33. data/lib/tapioca/loaders/gem.rb +4 -2
  34. data/lib/tapioca/loaders/loader.rb +99 -35
  35. data/lib/tapioca/rbi_ext/model.rb +8 -3
  36. data/lib/tapioca/rbi_formatter.rb +11 -8
  37. data/lib/tapioca/runtime/attached_class_of_32.rb +20 -0
  38. data/lib/tapioca/runtime/attached_class_of_legacy.rb +27 -0
  39. data/lib/tapioca/runtime/reflection.rb +11 -10
  40. data/lib/tapioca/runtime/trackers.rb +17 -0
  41. data/lib/tapioca/static/symbol_loader.rb +14 -14
  42. data/lib/tapioca/version.rb +1 -1
  43. data/lib/tapioca.rb +8 -5
  44. metadata +7 -2
@@ -164,16 +164,10 @@ module Tapioca
164
164
 
165
165
  sig { override.void }
166
166
  def decorate
167
- root.create_path(constant) do |model|
168
- relation_methods_module = model.create_module(RelationMethodsModuleName)
169
- association_relation_methods_module = model.create_module(AssociationRelationMethodsModuleName)
170
- common_relation_methods_module = model.create_module(CommonRelationMethodsModuleName)
171
-
172
- create_classes_and_includes(model)
173
- create_common_methods(common_relation_methods_module)
174
- create_relation_methods(relation_methods_module, association_relation_methods_module)
175
- create_association_relation_methods(association_relation_methods_module)
176
- end
167
+ create_classes_and_includes
168
+ create_common_methods
169
+ create_relation_methods
170
+ create_association_relation_methods
177
171
  end
178
172
 
179
173
  class << self
@@ -181,7 +175,7 @@ module Tapioca
181
175
 
182
176
  sig { override.returns(T::Enumerable[Module]) }
183
177
  def gather_constants
184
- ActiveRecord::Base.descendants.reject(&:abstract_class?)
178
+ descendants_of(ActiveRecord::Base).reject(&:abstract_class?)
185
179
  end
186
180
  end
187
181
 
@@ -196,28 +190,35 @@ module Tapioca
196
190
  T::Array[Symbol],
197
191
  )
198
192
 
199
- QUERY_METHODS = T.let(begin
200
- # Grab all Query methods
201
- query_methods = ActiveRecord::QueryMethods.instance_methods(false)
202
- # Grab all Spawn methods
203
- query_methods |= ActiveRecord::SpawnMethods.instance_methods(false)
204
- # Remove the ones we know are private API
205
- query_methods -= [:arel, :build_subquery, :construct_join_dependency, :extensions, :spawn]
206
- # Remove "where" which needs a custom return type for WhereChains
207
- query_methods -= [:where]
208
- # Remove the methods that ...
209
- query_methods
210
- .grep_v(/_clause$/) # end with "_clause"
211
- .grep_v(/_values?$/) # end with "_value" or "_values"
212
- .grep_v(/=$/) # end with "=""
213
- .grep_v(/(?<!uniq)!$/) # end with "!" except for "uniq!"
214
- end, T::Array[Symbol])
193
+ QUERY_METHODS = T.let(
194
+ begin
195
+ # Grab all Query methods
196
+ query_methods = ActiveRecord::QueryMethods.instance_methods(false)
197
+ # Grab all Spawn methods
198
+ query_methods |= ActiveRecord::SpawnMethods.instance_methods(false)
199
+ # Remove the ones we know are private API
200
+ query_methods -= [:arel, :build_subquery, :construct_join_dependency, :extensions, :spawn]
201
+ # Remove "where" which needs a custom return type for WhereChains
202
+ query_methods -= [:where]
203
+ # Remove the methods that ...
204
+ query_methods
205
+ .grep_v(/_clause$/) # end with "_clause"
206
+ .grep_v(/_values?$/) # end with "_value" or "_values"
207
+ .grep_v(/=$/) # end with "=""
208
+ .grep_v(/(?<!uniq)!$/) # end with "!" except for "uniq!"
209
+ end,
210
+ T::Array[Symbol],
211
+ )
215
212
  WHERE_CHAIN_QUERY_METHODS = T.let(
216
213
  ActiveRecord::QueryMethods::WhereChain.instance_methods(false),
217
214
  T::Array[Symbol],
218
215
  )
219
216
  FINDER_METHODS = T.let(ActiveRecord::FinderMethods.instance_methods(false), T::Array[Symbol])
220
- SIGNED_FINDER_METHODS = T.let(ActiveRecord::SignedId::ClassMethods.instance_methods(false), T::Array[Symbol])
217
+ SIGNED_FINDER_METHODS = T.let(
218
+ defined?(ActiveRecord::SignedId) ? ActiveRecord::SignedId::ClassMethods.instance_methods(false) : [],
219
+ T::Array[Symbol],
220
+ )
221
+ BATCHES_METHODS = T.let(ActiveRecord::Batches.instance_methods(false), T::Array[Symbol])
221
222
  CALCULATION_METHODS = T.let(ActiveRecord::Calculations.instance_methods(false), T::Array[Symbol])
222
223
  ENUMERABLE_QUERY_METHODS = T.let([:any?, :many?, :none?, :one?], T::Array[Symbol])
223
224
  FIND_OR_CREATE_METHODS = T.let(
@@ -228,6 +229,38 @@ module Tapioca
228
229
 
229
230
  private
230
231
 
232
+ sig { returns(RBI::Scope) }
233
+ def model
234
+ @model ||= T.let(
235
+ root.create_path(constant),
236
+ T.nilable(RBI::Scope),
237
+ )
238
+ end
239
+
240
+ sig { returns(RBI::Scope) }
241
+ def relation_methods_module
242
+ @relation_methods_module ||= T.let(
243
+ model.create_module(RelationMethodsModuleName),
244
+ T.nilable(RBI::Scope),
245
+ )
246
+ end
247
+
248
+ sig { returns(RBI::Scope) }
249
+ def association_relation_methods_module
250
+ @association_relation_methods_module ||= T.let(
251
+ model.create_module(AssociationRelationMethodsModuleName),
252
+ T.nilable(RBI::Scope),
253
+ )
254
+ end
255
+
256
+ sig { returns(RBI::Scope) }
257
+ def common_relation_methods_module
258
+ @common_relation_methods_module ||= T.let(
259
+ model.create_module(CommonRelationMethodsModuleName),
260
+ T.nilable(RBI::Scope),
261
+ )
262
+ end
263
+
231
264
  sig { returns(String) }
232
265
  def constant_name
233
266
  @constant_name ||= T.let(T.must(qualified_name_of(constant)), T.nilable(String))
@@ -238,8 +271,8 @@ module Tapioca
238
271
  method_name.to_s.end_with?("!")
239
272
  end
240
273
 
241
- sig { params(model: RBI::Scope).void }
242
- def create_classes_and_includes(model)
274
+ sig { void }
275
+ def create_classes_and_includes
243
276
  model.create_extend(CommonRelationMethodsModuleName)
244
277
  # The model always extends the generated relation module
245
278
  model.create_extend(RelationMethodsModuleName)
@@ -248,13 +281,13 @@ module Tapioca
248
281
  # See https://github.com/sorbet/sorbet/pull/4706 for details
249
282
  model.create_method("to_ary", return_type: "NilClass", visibility: RBI::Private.new)
250
283
 
251
- create_relation_class(model)
252
- create_association_relation_class(model)
253
- create_collection_proxy_class(model)
284
+ create_relation_class
285
+ create_association_relation_class
286
+ create_collection_proxy_class
254
287
  end
255
288
 
256
- sig { params(model: RBI::Scope).void }
257
- def create_relation_class(model)
289
+ sig { void }
290
+ def create_relation_class
258
291
  superclass = "::ActiveRecord::Relation"
259
292
 
260
293
  # The relation subclass includes the generated relation module
@@ -266,11 +299,11 @@ module Tapioca
266
299
  klass.create_method("to_ary", return_type: "T::Array[#{constant_name}]")
267
300
  end
268
301
 
269
- create_relation_where_chain_class(model)
302
+ create_relation_where_chain_class
270
303
  end
271
304
 
272
- sig { params(model: RBI::Scope).void }
273
- def create_association_relation_class(model)
305
+ sig { void }
306
+ def create_association_relation_class
274
307
  superclass = "::ActiveRecord::AssociationRelation"
275
308
 
276
309
  # Association subclasses include the generated association relation module
@@ -282,19 +315,19 @@ module Tapioca
282
315
  klass.create_method("to_ary", return_type: "T::Array[#{constant_name}]")
283
316
  end
284
317
 
285
- create_association_relation_where_chain_class(model)
318
+ create_association_relation_where_chain_class
286
319
  end
287
320
 
288
- sig { params(model: RBI::Scope).void }
289
- def create_relation_where_chain_class(model)
321
+ sig { void }
322
+ def create_relation_where_chain_class
290
323
  model.create_class(RelationWhereChainClassName, superclass_name: RelationClassName) do |klass|
291
324
  create_where_chain_methods(klass, RelationClassName)
292
325
  klass.create_type_variable("Elem", type: "type_member", fixed: constant_name)
293
326
  end
294
327
  end
295
328
 
296
- sig { params(model: RBI::Scope).void }
297
- def create_association_relation_where_chain_class(model)
329
+ sig { void }
330
+ def create_association_relation_where_chain_class
298
331
  model.create_class(
299
332
  AssociationRelationWhereChainClassName,
300
333
  superclass_name: AssociationRelationClassName,
@@ -329,8 +362,8 @@ module Tapioca
329
362
  end
330
363
  end
331
364
 
332
- sig { params(model: RBI::Scope).void }
333
- def create_collection_proxy_class(model)
365
+ sig { void }
366
+ def create_collection_proxy_class
334
367
  superclass = "::ActiveRecord::Associations::CollectionProxy"
335
368
 
336
369
  # The relation subclass includes the generated association relation module
@@ -423,13 +456,11 @@ module Tapioca
423
456
  end
424
457
  end
425
458
 
426
- sig { params(relation_methods_module: RBI::Scope, association_relation_methods_module: RBI::Scope).void }
427
- def create_relation_methods(relation_methods_module, association_relation_methods_module)
428
- create_relation_method("all", relation_methods_module, association_relation_methods_module)
459
+ sig { void }
460
+ def create_relation_methods
461
+ create_relation_method("all")
429
462
  create_relation_method(
430
463
  "where",
431
- relation_methods_module,
432
- association_relation_methods_module,
433
464
  parameters: [
434
465
  create_rest_param("args", type: "T.untyped"),
435
466
  create_block_param("blk", type: "T.untyped"),
@@ -441,8 +472,6 @@ module Tapioca
441
472
  QUERY_METHODS.each do |method_name|
442
473
  create_relation_method(
443
474
  method_name,
444
- relation_methods_module,
445
- association_relation_methods_module,
446
475
  parameters: [
447
476
  create_rest_param("args", type: "T.untyped"),
448
477
  create_block_param("blk", type: "T.untyped"),
@@ -451,8 +480,8 @@ module Tapioca
451
480
  end
452
481
  end
453
482
 
454
- sig { params(association_relation_methods_module: RBI::Scope).void }
455
- def create_association_relation_methods(association_relation_methods_module)
483
+ sig { void }
484
+ def create_association_relation_methods
456
485
  returning_type = "T.nilable(T.any(T::Array[Symbol], FalseClass))"
457
486
  unique_by_type = "T.nilable(T.any(T::Array[Symbol], Symbol))"
458
487
 
@@ -496,11 +525,10 @@ module Tapioca
496
525
  end
497
526
  end
498
527
 
499
- sig { params(common_relation_methods_module: RBI::Scope).void }
500
- def create_common_methods(common_relation_methods_module)
528
+ sig { void }
529
+ def create_common_methods
501
530
  create_common_method(
502
531
  "destroy_all",
503
- common_relation_methods_module,
504
532
  return_type: "T::Array[#{constant_name}]",
505
533
  )
506
534
 
@@ -509,7 +537,6 @@ module Tapioca
509
537
  when :exists?
510
538
  create_common_method(
511
539
  "exists?",
512
- common_relation_methods_module,
513
540
  parameters: [
514
541
  create_opt_param("conditions", type: "T.untyped", default: ":none"),
515
542
  ],
@@ -518,7 +545,6 @@ module Tapioca
518
545
  when :include?, :member?
519
546
  create_common_method(
520
547
  method_name,
521
- common_relation_methods_module,
522
548
  parameters: [
523
549
  create_param("record", type: "T.untyped"),
524
550
  ],
@@ -527,7 +553,6 @@ module Tapioca
527
553
  when :find
528
554
  create_common_method(
529
555
  "find",
530
- common_relation_methods_module,
531
556
  parameters: [
532
557
  create_rest_param("args", type: "T.untyped"),
533
558
  ],
@@ -536,7 +561,6 @@ module Tapioca
536
561
  when :find_by
537
562
  create_common_method(
538
563
  "find_by",
539
- common_relation_methods_module,
540
564
  parameters: [
541
565
  create_rest_param("args", type: "T.untyped"),
542
566
  ],
@@ -545,7 +569,6 @@ module Tapioca
545
569
  when :find_by!
546
570
  create_common_method(
547
571
  "find_by!",
548
- common_relation_methods_module,
549
572
  parameters: [
550
573
  create_rest_param("args", type: "T.untyped"),
551
574
  ],
@@ -554,7 +577,6 @@ module Tapioca
554
577
  when :find_sole_by
555
578
  create_common_method(
556
579
  "find_sole_by",
557
- common_relation_methods_module,
558
580
  parameters: [
559
581
  create_param("arg", type: "T.untyped"),
560
582
  create_rest_param("args", type: "T.untyped"),
@@ -564,14 +586,12 @@ module Tapioca
564
586
  when :sole
565
587
  create_common_method(
566
588
  "sole",
567
- common_relation_methods_module,
568
589
  parameters: [],
569
590
  return_type: constant_name,
570
591
  )
571
592
  when :first, :last, :take
572
593
  create_common_method(
573
594
  method_name,
574
- common_relation_methods_module,
575
595
  parameters: [
576
596
  create_opt_param("limit", type: "T.untyped", default: "nil"),
577
597
  ],
@@ -588,7 +608,6 @@ module Tapioca
588
608
 
589
609
  create_common_method(
590
610
  method_name,
591
- common_relation_methods_module,
592
611
  return_type: return_type,
593
612
  )
594
613
  end
@@ -599,7 +618,6 @@ module Tapioca
599
618
  when :find_signed
600
619
  create_common_method(
601
620
  "find_signed",
602
- common_relation_methods_module,
603
621
  parameters: [
604
622
  create_param("signed_id", type: "T.untyped"),
605
623
  create_kw_opt_param("purpose", type: "T.untyped", default: "nil"),
@@ -609,7 +627,6 @@ module Tapioca
609
627
  when :find_signed!
610
628
  create_common_method(
611
629
  "find_signed!",
612
- common_relation_methods_module,
613
630
  parameters: [
614
631
  create_param("signed_id", type: "T.untyped"),
615
632
  create_kw_opt_param("purpose", type: "T.untyped", default: "nil"),
@@ -624,7 +641,6 @@ module Tapioca
624
641
  when :average, :maximum, :minimum
625
642
  create_common_method(
626
643
  method_name,
627
- common_relation_methods_module,
628
644
  parameters: [
629
645
  create_param("column_name", type: "T.any(String, Symbol)"),
630
646
  ],
@@ -633,7 +649,6 @@ module Tapioca
633
649
  when :calculate
634
650
  create_common_method(
635
651
  "calculate",
636
- common_relation_methods_module,
637
652
  parameters: [
638
653
  create_param("operation", type: "Symbol"),
639
654
  create_param("column_name", type: "T.any(String, Symbol)"),
@@ -643,18 +658,16 @@ module Tapioca
643
658
  when :count
644
659
  create_common_method(
645
660
  "count",
646
- common_relation_methods_module,
647
661
  parameters: [
648
662
  create_opt_param("column_name", type: "T.untyped", default: "nil"),
649
663
  ],
650
664
  return_type: "T.untyped",
651
665
  )
652
666
  when :ids
653
- create_common_method("ids", common_relation_methods_module, return_type: "Array")
667
+ create_common_method("ids", return_type: "Array")
654
668
  when :pick, :pluck
655
669
  create_common_method(
656
670
  method_name,
657
- common_relation_methods_module,
658
671
  parameters: [
659
672
  create_rest_param("column_names", type: "T.untyped"),
660
673
  ],
@@ -663,7 +676,6 @@ module Tapioca
663
676
  when :sum
664
677
  create_common_method(
665
678
  "sum",
666
- common_relation_methods_module,
667
679
  parameters: [
668
680
  create_opt_param("column_name", type: "T.nilable(T.any(String, Symbol))", default: "nil"),
669
681
  create_block_param("block", type: "T.nilable(T.proc.params(record: T.untyped).returns(T.untyped))"),
@@ -673,11 +685,63 @@ module Tapioca
673
685
  end
674
686
  end
675
687
 
688
+ BATCHES_METHODS.each do |method_name|
689
+ case method_name
690
+ when :find_each
691
+ order = ActiveRecord::Batches.instance_method(:find_each).parameters.include?([:key, :order])
692
+ create_common_method(
693
+ "find_each",
694
+ parameters: [
695
+ create_kw_opt_param("start", type: "T.untyped", default: "nil"),
696
+ create_kw_opt_param("finish", type: "T.untyped", default: "nil"),
697
+ create_kw_opt_param("batch_size", type: "Integer", default: "1000"),
698
+ create_kw_opt_param("error_on_ignore", type: "T.untyped", default: "nil"),
699
+ *(create_kw_opt_param("order", type: "Symbol", default: ":asc") if order),
700
+ create_block_param("block", type: "T.nilable(T.proc.params(object: #{constant_name}).void)"),
701
+ ],
702
+ return_type: "T.nilable(T::Enumerator[#{constant_name}])",
703
+ )
704
+ when :find_in_batches
705
+ order = ActiveRecord::Batches.instance_method(:find_in_batches).parameters.include?([:key, :order])
706
+ create_common_method(
707
+ "find_in_batches",
708
+ parameters: [
709
+ create_kw_opt_param("start", type: "T.untyped", default: "nil"),
710
+ create_kw_opt_param("finish", type: "T.untyped", default: "nil"),
711
+ create_kw_opt_param("batch_size", type: "Integer", default: "1000"),
712
+ create_kw_opt_param("error_on_ignore", type: "T.untyped", default: "nil"),
713
+ *(create_kw_opt_param("order", type: "Symbol", default: ":asc") if order),
714
+ create_block_param(
715
+ "block",
716
+ type: "T.nilable(T.proc.params(object: T::Array[#{constant_name}]).void)",
717
+ ),
718
+ ],
719
+ return_type: "T.nilable(T::Enumerator[T::Enumerator[#{constant_name}]])",
720
+ )
721
+ when :in_batches
722
+ order = ActiveRecord::Batches.instance_method(:in_batches).parameters.include?([:key, :order])
723
+ use_ranges = ActiveRecord::Batches.instance_method(:in_batches).parameters.include?([:key, :use_ranges])
724
+ create_common_method(
725
+ "in_batches",
726
+ parameters: [
727
+ create_kw_opt_param("of", type: "Integer", default: "1000"),
728
+ create_kw_opt_param("start", type: "T.untyped", default: "nil"),
729
+ create_kw_opt_param("finish", type: "T.untyped", default: "nil"),
730
+ create_kw_opt_param("load", type: "T.untyped", default: "false"),
731
+ create_kw_opt_param("error_on_ignore", type: "T.untyped", default: "nil"),
732
+ *(create_kw_opt_param("order", type: "Symbol", default: ":asc") if order),
733
+ *(create_kw_opt_param("use_ranges", type: "T.untyped", default: "nil") if use_ranges),
734
+ create_block_param("block", type: "T.nilable(T.proc.params(object: #{RelationClassName}).void)"),
735
+ ],
736
+ return_type: "T.nilable(::ActiveRecord::Batches::BatchEnumerator)",
737
+ )
738
+ end
739
+ end
740
+
676
741
  ENUMERABLE_QUERY_METHODS.each do |method_name|
677
742
  block_type = "T.nilable(T.proc.params(record: #{constant_name}).returns(T.untyped))"
678
743
  create_common_method(
679
744
  method_name,
680
- common_relation_methods_module,
681
745
  parameters: [
682
746
  create_block_param("block", type: block_type),
683
747
  ],
@@ -689,7 +753,6 @@ module Tapioca
689
753
  block_type = "T.nilable(T.proc.params(object: #{constant_name}).void)"
690
754
  create_common_method(
691
755
  method_name,
692
- common_relation_methods_module,
693
756
  parameters: [
694
757
  create_param("attributes", type: "T.untyped"),
695
758
  create_block_param("block", type: block_type),
@@ -701,7 +764,6 @@ module Tapioca
701
764
  BUILDER_METHODS.each do |method_name|
702
765
  create_common_method(
703
766
  method_name,
704
- common_relation_methods_module,
705
767
  parameters: [
706
768
  create_opt_param("attributes", type: "T.untyped", default: "nil"),
707
769
  create_block_param("block", type: "T.nilable(T.proc.params(object: #{constant_name}).void)"),
@@ -714,12 +776,11 @@ module Tapioca
714
776
  sig do
715
777
  params(
716
778
  name: T.any(Symbol, String),
717
- common_relation_methods_module: RBI::Scope,
718
779
  parameters: T::Array[RBI::TypedParam],
719
780
  return_type: T.nilable(String),
720
781
  ).void
721
782
  end
722
- def create_common_method(name, common_relation_methods_module, parameters: [], return_type: nil)
783
+ def create_common_method(name, parameters: [], return_type: nil)
723
784
  common_relation_methods_module.create_method(
724
785
  name.to_s,
725
786
  parameters: parameters,
@@ -730,8 +791,6 @@ module Tapioca
730
791
  sig do
731
792
  params(
732
793
  name: T.any(Symbol, String),
733
- relation_methods_module: RBI::Scope,
734
- association_relation_methods_module: RBI::Scope,
735
794
  parameters: T::Array[RBI::TypedParam],
736
795
  relation_return_type: String,
737
796
  association_return_type: String,
@@ -739,8 +798,6 @@ module Tapioca
739
798
  end
740
799
  def create_relation_method(
741
800
  name,
742
- relation_methods_module,
743
- association_relation_methods_module,
744
801
  parameters: [],
745
802
  relation_return_type: RelationClassName,
746
803
  association_return_type: AssociationRelationClassName
@@ -83,7 +83,7 @@ module Tapioca
83
83
  class << self
84
84
  sig { override.returns(T::Enumerable[Module]) }
85
85
  def gather_constants
86
- descendants_of(::ActiveRecord::Base).reject(&:abstract_class?)
86
+ descendants_of(::ActiveRecord::Base)
87
87
  end
88
88
  end
89
89
 
@@ -0,0 +1,74 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ begin
5
+ require "active_record"
6
+ rescue LoadError
7
+ return
8
+ end
9
+
10
+ require "tapioca/dsl/helpers/active_record_constants_helper"
11
+
12
+ module Tapioca
13
+ module Dsl
14
+ module Compilers
15
+ # `Tapioca::Dsl::Compilers::ActiveModelSecurePassword` decorates RBI files for all
16
+ # classes that use [`ActiveRecord::SecureToken`](https://api.rubyonrails.org/classes/ActiveRecord/SecureToken/ClassMethods.html).
17
+ #
18
+ # For example, with the following class:
19
+ #
20
+ # ~~~rb
21
+ # class User < ActiveRecord::Base
22
+ # has_secure_token
23
+ # has_secure_token :auth_token, length: 36
24
+ # end
25
+ # ~~~
26
+ #
27
+ # this compiler will produce an RBI file with the following content:
28
+ # ~~~rbi
29
+ # # typed: true
30
+ #
31
+ # class User
32
+ # sig { returns(T::Boolean) }
33
+ # def regenerate_token; end
34
+ #
35
+ # sig { returns(T::Boolean) }
36
+ # def regenerate_auth_token; end
37
+ # end
38
+ # ~~~
39
+ class ActiveRecordSecureToken < Compiler
40
+ extend T::Sig
41
+ include Helpers::ActiveRecordConstantsHelper
42
+
43
+ ConstantType = type_member { { fixed: T.all(T.class_of(ActiveRecord::Base), Extensions::ActiveRecord) } }
44
+
45
+ sig { override.void }
46
+ def decorate
47
+ return if constant.__tapioca_secure_tokens.nil?
48
+
49
+ root.create_path(constant) do |model|
50
+ model.create_module(SecureTokensModuleName) do |mod|
51
+ constant.__tapioca_secure_tokens.each do |attribute|
52
+ mod.create_method(
53
+ "regenerate_#{attribute}",
54
+ return_type: "T::Boolean",
55
+ )
56
+ end
57
+ end
58
+
59
+ model.create_include(SecureTokensModuleName)
60
+ end
61
+ end
62
+
63
+ class << self
64
+ extend T::Sig
65
+
66
+ sig { override.returns(T::Enumerable[Module]) }
67
+ def gather_constants
68
+ descendants_of(::ActiveRecord::Base).reject(&:abstract_class?)
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -126,17 +126,20 @@ module Tapioca
126
126
 
127
127
  private
128
128
 
129
- TYPES = T.let({
130
- boolean: "T::Boolean",
131
- integer: "Integer",
132
- string: "String",
133
- float: "Float",
134
- date: "Date",
135
- time: "Time",
136
- datetime: "DateTime",
137
- decimal: "BigDecimal",
138
- any: "T.untyped",
139
- }.freeze, T::Hash[Symbol, String])
129
+ TYPES = T.let(
130
+ {
131
+ boolean: "T::Boolean",
132
+ integer: "Integer",
133
+ string: "String",
134
+ float: "Float",
135
+ date: "Date",
136
+ time: "Time",
137
+ datetime: "DateTime",
138
+ decimal: "BigDecimal",
139
+ any: "T.untyped",
140
+ }.freeze,
141
+ T::Hash[Symbol, String],
142
+ )
140
143
 
141
144
  sig { params(attr_type: Symbol).returns(String) }
142
145
  def type_for(attr_type)
@@ -85,18 +85,21 @@ module Tapioca
85
85
 
86
86
  private
87
87
 
88
- TYPES = T.let({
89
- boolean: "T::Boolean",
90
- integer: "Integer",
91
- string: "String",
92
- float: "Float",
93
- date: "Date",
94
- time: "Time",
95
- datetime: "DateTime",
96
- decimal: "BigDecimal",
97
- binary: "String",
98
- text: "String",
99
- }.freeze, T::Hash[Symbol, String])
88
+ TYPES = T.let(
89
+ {
90
+ boolean: "T::Boolean",
91
+ integer: "Integer",
92
+ string: "String",
93
+ float: "Float",
94
+ date: "Date",
95
+ time: "Time",
96
+ datetime: "DateTime",
97
+ decimal: "BigDecimal",
98
+ binary: "String",
99
+ text: "String",
100
+ }.freeze,
101
+ T::Hash[Symbol, String],
102
+ )
100
103
 
101
104
  sig { params(attr_type: Symbol).returns(String) }
102
105
  def type_for(attr_type)
@@ -109,9 +112,13 @@ module Tapioca
109
112
 
110
113
  klass.create_method(attribute, return_type: return_type)
111
114
  klass.create_method("#{attribute}?", return_type: "T::Boolean")
112
- klass.create_method("#{attribute}=", parameters: [
113
- create_param("value", type: return_type),
114
- ], return_type: return_type)
115
+ klass.create_method(
116
+ "#{attribute}=",
117
+ parameters: [
118
+ create_param("value", type: return_type),
119
+ ],
120
+ return_type: return_type,
121
+ )
115
122
  end
116
123
  end
117
124
  end
@@ -48,8 +48,10 @@ module Tapioca
48
48
 
49
49
  ConstantType = type_member do
50
50
  {
51
- fixed: T.all(Module,
52
- ::ActiveStorage::Reflection::ActiveRecordExtensions::ClassMethods),
51
+ fixed: T.all(
52
+ Module,
53
+ ::ActiveStorage::Reflection::ActiveRecordExtensions::ClassMethods,
54
+ ),
53
55
  }
54
56
  end
55
57