tapioca 0.11.17 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +122 -100
  3. data/lib/tapioca/commands/abstract_dsl.rb +3 -2
  4. data/lib/tapioca/commands/abstract_gem.rb +3 -1
  5. data/lib/tapioca/dsl/compilers/aasm.rb +1 -6
  6. data/lib/tapioca/dsl/compilers/action_controller_helpers.rb +1 -5
  7. data/lib/tapioca/dsl/compilers/action_mailer.rb +1 -5
  8. data/lib/tapioca/dsl/compilers/action_text.rb +1 -5
  9. data/lib/tapioca/dsl/compilers/active_job.rb +1 -5
  10. data/lib/tapioca/dsl/compilers/active_model_attributes.rb +4 -11
  11. data/lib/tapioca/dsl/compilers/active_model_secure_password.rb +10 -6
  12. data/lib/tapioca/dsl/compilers/active_model_validations_confirmation.rb +1 -5
  13. data/lib/tapioca/dsl/compilers/active_record_associations.rb +1 -5
  14. data/lib/tapioca/dsl/compilers/active_record_columns.rb +1 -5
  15. data/lib/tapioca/dsl/compilers/active_record_delegated_types.rb +1 -5
  16. data/lib/tapioca/dsl/compilers/active_record_enum.rb +1 -7
  17. data/lib/tapioca/dsl/compilers/active_record_fixtures.rb +2 -9
  18. data/lib/tapioca/dsl/compilers/active_record_relations.rb +253 -66
  19. data/lib/tapioca/dsl/compilers/active_record_scope.rb +1 -5
  20. data/lib/tapioca/dsl/compilers/active_record_secure_token.rb +1 -5
  21. data/lib/tapioca/dsl/compilers/active_record_store.rb +1 -5
  22. data/lib/tapioca/dsl/compilers/active_record_typed_store.rb +1 -7
  23. data/lib/tapioca/dsl/compilers/active_resource.rb +1 -5
  24. data/lib/tapioca/dsl/compilers/active_storage.rb +1 -6
  25. data/lib/tapioca/dsl/compilers/active_support_concern.rb +1 -5
  26. data/lib/tapioca/dsl/compilers/active_support_current_attributes.rb +6 -16
  27. data/lib/tapioca/dsl/compilers/config.rb +1 -5
  28. data/lib/tapioca/dsl/compilers/frozen_record.rb +1 -5
  29. data/lib/tapioca/dsl/compilers/graphql_input_object.rb +2 -6
  30. data/lib/tapioca/dsl/compilers/graphql_mutation.rb +2 -6
  31. data/lib/tapioca/dsl/compilers/identity_cache.rb +1 -7
  32. data/lib/tapioca/dsl/compilers/json_api_client_resource.rb +1 -7
  33. data/lib/tapioca/dsl/compilers/kredis.rb +1 -5
  34. data/lib/tapioca/dsl/compilers/mixed_in_class_attributes.rb +1 -5
  35. data/lib/tapioca/dsl/compilers/protobuf.rb +8 -5
  36. data/lib/tapioca/dsl/compilers/rails_generators.rb +1 -6
  37. data/lib/tapioca/dsl/compilers/sidekiq_worker.rb +1 -5
  38. data/lib/tapioca/dsl/compilers/smart_properties.rb +1 -7
  39. data/lib/tapioca/dsl/compilers/state_machines.rb +1 -7
  40. data/lib/tapioca/dsl/compilers/url_helpers.rb +17 -16
  41. data/lib/tapioca/dsl/extensions/active_record.rb +4 -2
  42. data/lib/tapioca/dsl/extensions/frozen_record.rb +6 -2
  43. data/lib/tapioca/dsl/extensions/kredis.rb +6 -2
  44. data/lib/tapioca/dsl/helpers/active_model_type_helper.rb +70 -0
  45. data/lib/tapioca/dsl/helpers/active_record_column_type_helper.rb +3 -35
  46. data/lib/tapioca/dsl/helpers/active_record_constants_helper.rb +2 -0
  47. data/lib/tapioca/dsl/pipeline.rb +1 -1
  48. data/lib/tapioca/gem/listeners/sorbet_props.rb +2 -1
  49. data/lib/tapioca/gemfile.rb +12 -1
  50. data/lib/tapioca/rbi_ext/model.rb +38 -6
  51. data/lib/tapioca/version.rb +1 -1
  52. metadata +6 -11
@@ -1,11 +1,7 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- begin
5
- require "active_record"
6
- rescue LoadError
7
- return
8
- end
4
+ return unless defined?(ActiveRecord::Base)
9
5
 
10
6
  require "tapioca/dsl/helpers/active_record_constants_helper"
11
7
 
@@ -62,16 +58,6 @@ module Tapioca
62
58
  # `Model::PrivateRelation` modules, so that, for example, `find_by` and `all` can be chained off of the
63
59
  # `Model` class.
64
60
  #
65
- # **A note on find**: `find` is typed as `T.untyped` by default.
66
- #
67
- # While it is often used in the manner of `Model.find(id)`, Rails does support pasing in an array to find, which
68
- # would then return a `T::Enumerable[Model]`. This would force a static cast everywhere find is used to avoid type
69
- # errors. This is not ideal considering very few users of find use the array syntax over a where. With untyped,
70
- # this cast is optional and so it was decided to avoid typing it. If you need runtime guarentees when using `find`
71
- # the best method of doing so is by casting the return value to the model: `T.cast(Model.find(id), Model)`.
72
- # `find_by` does guarentee a return value of `Model`, so find can can be refactored accordingly:
73
- # `Model.find_by!(id: id)`. This will avoid the cast requirement at runtime.
74
- #
75
61
  # **CAUTION**: The generated relation classes are named `PrivateXXX` intentionally to reflect the fact
76
62
  # that they represent private subconstants of the Active Record model. As such, these types do not
77
63
  # exist at runtime, and their counterparts that do exist at runtime are marked `private_constant` anyway.
@@ -204,6 +190,8 @@ module Tapioca
204
190
  query_methods |= ActiveRecord::SpawnMethods.instance_methods(false)
205
191
  # Remove the ones we know are private API
206
192
  query_methods -= [:arel, :build_subquery, :construct_join_dependency, :extensions, :spawn]
193
+ # Remove "group" which needs a custom return type for GroupChains
194
+ query_methods -= [:group]
207
195
  # Remove "where" which needs a custom return type for WhereChains
208
196
  query_methods -= [:where]
209
197
  # Remove the methods that ...
@@ -308,6 +296,7 @@ module Tapioca
308
296
  end
309
297
  end
310
298
 
299
+ create_relation_group_chain_class
311
300
  create_relation_where_chain_class
312
301
  end
313
302
 
@@ -326,9 +315,87 @@ module Tapioca
326
315
  end
327
316
  end
328
317
 
318
+ create_association_relation_group_chain_class
329
319
  create_association_relation_where_chain_class
330
320
  end
331
321
 
322
+ sig { void }
323
+ def create_relation_group_chain_class
324
+ model.create_class(RelationGroupChainClassName, superclass_name: RelationClassName) do |klass|
325
+ create_group_chain_methods(klass)
326
+ klass.create_type_variable("Elem", type: "type_member", fixed: constant_name)
327
+ end
328
+ end
329
+
330
+ sig { void }
331
+ def create_association_relation_group_chain_class
332
+ model.create_class(
333
+ AssociationRelationGroupChainClassName,
334
+ superclass_name: AssociationRelationClassName,
335
+ ) do |klass|
336
+ create_group_chain_methods(klass)
337
+ klass.create_type_variable("Elem", type: "type_member", fixed: constant_name)
338
+ end
339
+ end
340
+
341
+ sig { params(klass: RBI::Scope).void }
342
+ def create_group_chain_methods(klass)
343
+ # Calculation methods used with `group` return a hash where the keys cannot be typed
344
+ # but the values can. Technically a `group` anywhere in the query chain produces
345
+ # this behavior but to avoid needing to re-type every query method inside this module
346
+ # we make a simplifying assumption that the calculation method is called immediately
347
+ # after the group (e.g. `group().count` and not `group().where().count`). The one
348
+ # exception is `group().having().count` which is fairly idiomatic so that gets handled
349
+ # without breaking the chain.
350
+ klass.create_method(
351
+ "having",
352
+ parameters: [
353
+ create_rest_param("args", type: "T.untyped"),
354
+ create_block_param("blk", type: "T.untyped"),
355
+ ],
356
+ return_type: "T.self_type",
357
+ )
358
+
359
+ CALCULATION_METHODS.each do |method_name|
360
+ case method_name
361
+ when :average, :maximum, :minimum
362
+ klass.create_method(
363
+ method_name.to_s,
364
+ parameters: [
365
+ create_param("column_name", type: "T.any(String, Symbol)"),
366
+ ],
367
+ return_type: "T::Hash[T.untyped, #{method_name == :average ? "Numeric" : "T.untyped"}]",
368
+ )
369
+ when :calculate
370
+ klass.create_method(
371
+ "calculate",
372
+ parameters: [
373
+ create_param("operation", type: "Symbol"),
374
+ create_param("column_name", type: "T.any(String, Symbol)"),
375
+ ],
376
+ return_type: "T::Hash[T.untyped, Numeric]",
377
+ )
378
+ when :count
379
+ klass.create_method(
380
+ "count",
381
+ parameters: [
382
+ create_opt_param("column_name", type: "T.untyped", default: "nil"),
383
+ ],
384
+ return_type: "T::Hash[T.untyped, Integer]",
385
+ )
386
+ when :sum
387
+ klass.create_method(
388
+ "sum",
389
+ parameters: [
390
+ create_opt_param("column_name", type: "T.nilable(T.any(String, Symbol))", default: "nil"),
391
+ create_block_param("block", type: "T.nilable(T.proc.params(record: T.untyped).returns(T.untyped))"),
392
+ ],
393
+ return_type: "T::Hash[T.untyped, Numeric]",
394
+ )
395
+ end
396
+ end
397
+ end
398
+
332
399
  sig { void }
333
400
  def create_relation_where_chain_class
334
401
  model.create_class(RelationWhereChainClassName, superclass_name: RelationClassName) do |klass|
@@ -472,6 +539,15 @@ module Tapioca
472
539
  sig { void }
473
540
  def create_relation_methods
474
541
  create_relation_method("all")
542
+ create_relation_method(
543
+ "group",
544
+ parameters: [
545
+ create_rest_param("args", type: "T.untyped"),
546
+ create_block_param("blk", type: "T.untyped"),
547
+ ],
548
+ relation_return_type: RelationGroupChainClassName,
549
+ association_return_type: AssociationRelationGroupChainClassName,
550
+ )
475
551
  create_relation_method(
476
552
  "where",
477
553
  parameters: [
@@ -483,13 +559,29 @@ module Tapioca
483
559
  )
484
560
 
485
561
  QUERY_METHODS.each do |method_name|
486
- create_relation_method(
487
- method_name,
488
- parameters: [
489
- create_rest_param("args", type: "T.untyped"),
490
- create_block_param("blk", type: "T.untyped"),
491
- ],
492
- )
562
+ case method_name
563
+ when :extract_associated
564
+ parameters = [create_param("association", type: "Symbol")]
565
+ return_type = "T::Array[T.untyped]"
566
+ relation_methods_module.create_method(
567
+ method_name.to_s,
568
+ parameters: parameters,
569
+ return_type: return_type,
570
+ )
571
+ association_relation_methods_module.create_method(
572
+ method_name.to_s,
573
+ parameters: parameters,
574
+ return_type: return_type,
575
+ )
576
+ else
577
+ create_relation_method(
578
+ method_name,
579
+ parameters: [
580
+ create_rest_param("args", type: "T.untyped"),
581
+ create_block_param("blk", type: "T.untyped"),
582
+ ],
583
+ )
584
+ end
493
585
  end
494
586
  end
495
587
 
@@ -564,12 +656,29 @@ module Tapioca
564
656
  return_type: "T::Boolean",
565
657
  )
566
658
  when :find
567
- create_common_method(
659
+ # From ActiveRecord::ConnectionAdapter::Quoting#quote, minus nil
660
+ id_types = "T.any(String, Symbol, ::ActiveSupport::Multibyte::Chars, T::Boolean, BigDecimal, Numeric, " \
661
+ "::ActiveRecord::Type::Binary::Data, ::ActiveRecord::Type::Time::Value, Date, Time, " \
662
+ "::ActiveSupport::Duration, T::Class[T.anything])"
663
+ array_type = if constant.try(:composite_primary_key?)
664
+ "T::Array[T::Array[#{id_types}]"
665
+ else
666
+ "T::Array[#{id_types}]"
667
+ end
668
+ sigs = [
669
+ common_relation_methods_module.create_sig(
670
+ parameters: [create_param("args", type: id_types)],
671
+ return_type: constant_name,
672
+ ),
673
+ common_relation_methods_module.create_sig(
674
+ parameters: [create_param("args", type: array_type)],
675
+ return_type: "T::Enumerable[#{constant_name}]",
676
+ ),
677
+ ]
678
+ common_relation_methods_module.create_method_with_sigs(
568
679
  "find",
569
- parameters: [
570
- create_rest_param("args", type: "T.untyped"),
571
- ],
572
- return_type: "T.untyped",
680
+ sigs: sigs,
681
+ parameters: [RBI::ReqParam.new("args")],
573
682
  )
574
683
  when :find_by
575
684
  create_common_method(
@@ -603,12 +712,20 @@ module Tapioca
603
712
  return_type: constant_name,
604
713
  )
605
714
  when :first, :last, :take
606
- create_common_method(
607
- method_name,
608
- parameters: [
609
- create_opt_param("limit", type: "T.untyped", default: "nil"),
610
- ],
611
- return_type: "T.untyped",
715
+ sigs = [
716
+ common_relation_methods_module.create_sig(
717
+ parameters: [create_opt_param("limit", type: "NilClass", default: "nil")],
718
+ return_type: as_nilable_type(constant_name),
719
+ ),
720
+ common_relation_methods_module.create_sig(
721
+ parameters: [create_param("limit", type: "Integer")],
722
+ return_type: "T::Array[#{constant_name}]",
723
+ ),
724
+ ]
725
+ common_relation_methods_module.create_method_with_sigs(
726
+ method_name.to_s,
727
+ sigs: sigs,
728
+ parameters: [RBI::OptParam.new("limit", "nil")],
612
729
  )
613
730
  when :raise_record_not_found_exception!
614
731
  # skip
@@ -657,7 +774,7 @@ module Tapioca
657
774
  parameters: [
658
775
  create_param("column_name", type: "T.any(String, Symbol)"),
659
776
  ],
660
- return_type: "T.untyped",
777
+ return_type: method_name == :average ? "Numeric" : "T.untyped",
661
778
  )
662
779
  when :calculate
663
780
  create_common_method(
@@ -666,7 +783,7 @@ module Tapioca
666
783
  create_param("operation", type: "Symbol"),
667
784
  create_param("column_name", type: "T.any(String, Symbol)"),
668
785
  ],
669
- return_type: "T.untyped",
786
+ return_type: "Numeric",
670
787
  )
671
788
  when :count
672
789
  create_common_method(
@@ -674,7 +791,7 @@ module Tapioca
674
791
  parameters: [
675
792
  create_opt_param("column_name", type: "T.untyped", default: "nil"),
676
793
  ],
677
- return_type: "T.untyped",
794
+ return_type: "Integer",
678
795
  )
679
796
  when :ids
680
797
  create_common_method("ids", return_type: "Array")
@@ -693,7 +810,7 @@ module Tapioca
693
810
  create_opt_param("column_name", type: "T.nilable(T.any(String, Symbol))", default: "nil"),
694
811
  create_block_param("block", type: "T.nilable(T.proc.params(record: T.untyped).returns(T.untyped))"),
695
812
  ],
696
- return_type: "T.untyped",
813
+ return_type: "Numeric",
697
814
  )
698
815
  end
699
816
  end
@@ -702,51 +819,121 @@ module Tapioca
702
819
  case method_name
703
820
  when :find_each
704
821
  order = ActiveRecord::Batches.instance_method(:find_each).parameters.include?([:key, :order])
705
- create_common_method(
822
+ sigs = [
823
+ common_relation_methods_module.create_sig(
824
+ parameters: [
825
+ create_kw_opt_param("start", type: "T.untyped", default: "nil"),
826
+ create_kw_opt_param("finish", type: "T.untyped", default: "nil"),
827
+ create_kw_opt_param("batch_size", type: "Integer", default: "1000"),
828
+ create_kw_opt_param("error_on_ignore", type: "T.untyped", default: "nil"),
829
+ *(create_kw_opt_param("order", type: "Symbol", default: ":asc") if order),
830
+ create_block_param("block", type: "T.proc.params(object: #{constant_name}).void"),
831
+ ],
832
+ return_type: "void",
833
+ ),
834
+ common_relation_methods_module.create_sig(
835
+ parameters: [
836
+ create_kw_opt_param("start", type: "T.untyped", default: "nil"),
837
+ create_kw_opt_param("finish", type: "T.untyped", default: "nil"),
838
+ create_kw_opt_param("batch_size", type: "Integer", default: "1000"),
839
+ create_kw_opt_param("error_on_ignore", type: "T.untyped", default: "nil"),
840
+ *(create_kw_opt_param("order", type: "Symbol", default: ":asc") if order),
841
+ ],
842
+ return_type: "T::Enumerator[#{constant_name}]",
843
+ ),
844
+ ]
845
+ common_relation_methods_module.create_method_with_sigs(
706
846
  "find_each",
847
+ sigs: sigs,
707
848
  parameters: [
708
- create_kw_opt_param("start", type: "T.untyped", default: "nil"),
709
- create_kw_opt_param("finish", type: "T.untyped", default: "nil"),
710
- create_kw_opt_param("batch_size", type: "Integer", default: "1000"),
711
- create_kw_opt_param("error_on_ignore", type: "T.untyped", default: "nil"),
712
- *(create_kw_opt_param("order", type: "Symbol", default: ":asc") if order),
713
- create_block_param("block", type: "T.nilable(T.proc.params(object: #{constant_name}).void)"),
849
+ RBI::KwOptParam.new("start", "nil"),
850
+ RBI::KwOptParam.new("finish", "nil"),
851
+ RBI::KwOptParam.new("batch_size", "1000"),
852
+ RBI::KwOptParam.new("error_on_ignore", "nil"),
853
+ *(RBI::KwOptParam.new("order", ":asc") if order),
854
+ RBI::BlockParam.new("block"),
714
855
  ],
715
- return_type: "T.nilable(T::Enumerator[#{constant_name}])",
716
856
  )
717
857
  when :find_in_batches
718
858
  order = ActiveRecord::Batches.instance_method(:find_in_batches).parameters.include?([:key, :order])
719
- create_common_method(
859
+ sigs = [
860
+ common_relation_methods_module.create_sig(
861
+ parameters: [
862
+ create_kw_opt_param("start", type: "T.untyped", default: "nil"),
863
+ create_kw_opt_param("finish", type: "T.untyped", default: "nil"),
864
+ create_kw_opt_param("batch_size", type: "Integer", default: "1000"),
865
+ create_kw_opt_param("error_on_ignore", type: "T.untyped", default: "nil"),
866
+ *(create_kw_opt_param("order", type: "Symbol", default: ":asc") if order),
867
+ create_block_param("block", type: "T.proc.params(object: T::Array[#{constant_name}]).void"),
868
+ ],
869
+ return_type: "void",
870
+ ),
871
+ common_relation_methods_module.create_sig(
872
+ parameters: [
873
+ create_kw_opt_param("start", type: "T.untyped", default: "nil"),
874
+ create_kw_opt_param("finish", type: "T.untyped", default: "nil"),
875
+ create_kw_opt_param("batch_size", type: "Integer", default: "1000"),
876
+ create_kw_opt_param("error_on_ignore", type: "T.untyped", default: "nil"),
877
+ *(create_kw_opt_param("order", type: "Symbol", default: ":asc") if order),
878
+ ],
879
+ return_type: "T::Enumerator[T::Enumerator[#{constant_name}]]",
880
+ ),
881
+ ]
882
+ common_relation_methods_module.create_method_with_sigs(
720
883
  "find_in_batches",
884
+ sigs: sigs,
721
885
  parameters: [
722
- create_kw_opt_param("start", type: "T.untyped", default: "nil"),
723
- create_kw_opt_param("finish", type: "T.untyped", default: "nil"),
724
- create_kw_opt_param("batch_size", type: "Integer", default: "1000"),
725
- create_kw_opt_param("error_on_ignore", type: "T.untyped", default: "nil"),
726
- *(create_kw_opt_param("order", type: "Symbol", default: ":asc") if order),
727
- create_block_param(
728
- "block",
729
- type: "T.nilable(T.proc.params(object: T::Array[#{constant_name}]).void)",
730
- ),
886
+ RBI::KwOptParam.new("start", "nil"),
887
+ RBI::KwOptParam.new("finish", "nil"),
888
+ RBI::KwOptParam.new("batch_size", "1000"),
889
+ RBI::KwOptParam.new("error_on_ignore", "nil"),
890
+ *(RBI::KwOptParam.new("order", ":asc") if order),
891
+ RBI::BlockParam.new("block"),
731
892
  ],
732
- return_type: "T.nilable(T::Enumerator[T::Enumerator[#{constant_name}]])",
733
893
  )
734
894
  when :in_batches
735
895
  order = ActiveRecord::Batches.instance_method(:in_batches).parameters.include?([:key, :order])
736
896
  use_ranges = ActiveRecord::Batches.instance_method(:in_batches).parameters.include?([:key, :use_ranges])
737
- create_common_method(
897
+ sigs = [
898
+ common_relation_methods_module.create_sig(
899
+ parameters: [
900
+ create_kw_opt_param("of", type: "Integer", default: "1000"),
901
+ create_kw_opt_param("start", type: "T.untyped", default: "nil"),
902
+ create_kw_opt_param("finish", type: "T.untyped", default: "nil"),
903
+ create_kw_opt_param("load", type: "T.untyped", default: "false"),
904
+ create_kw_opt_param("error_on_ignore", type: "T.untyped", default: "nil"),
905
+ *(create_kw_opt_param("order", type: "Symbol", default: ":asc") if order),
906
+ *(create_kw_opt_param("use_ranges", type: "T.untyped", default: "nil") if use_ranges),
907
+ create_block_param("block", type: "T.proc.params(object: #{RelationClassName}).void"),
908
+ ],
909
+ return_type: "void",
910
+ ),
911
+ common_relation_methods_module.create_sig(
912
+ parameters: [
913
+ create_kw_opt_param("of", type: "Integer", default: "1000"),
914
+ create_kw_opt_param("start", type: "T.untyped", default: "nil"),
915
+ create_kw_opt_param("finish", type: "T.untyped", default: "nil"),
916
+ create_kw_opt_param("load", type: "T.untyped", default: "false"),
917
+ create_kw_opt_param("error_on_ignore", type: "T.untyped", default: "nil"),
918
+ *(create_kw_opt_param("order", type: "Symbol", default: ":asc") if order),
919
+ *(create_kw_opt_param("use_ranges", type: "T.untyped", default: "nil") if use_ranges),
920
+ ],
921
+ return_type: "::ActiveRecord::Batches::BatchEnumerator",
922
+ ),
923
+ ]
924
+ common_relation_methods_module.create_method_with_sigs(
738
925
  "in_batches",
926
+ sigs: sigs,
739
927
  parameters: [
740
- create_kw_opt_param("of", type: "Integer", default: "1000"),
741
- create_kw_opt_param("start", type: "T.untyped", default: "nil"),
742
- create_kw_opt_param("finish", type: "T.untyped", default: "nil"),
743
- create_kw_opt_param("load", type: "T.untyped", default: "false"),
744
- create_kw_opt_param("error_on_ignore", type: "T.untyped", default: "nil"),
745
- *(create_kw_opt_param("order", type: "Symbol", default: ":asc") if order),
746
- *(create_kw_opt_param("use_ranges", type: "T.untyped", default: "nil") if use_ranges),
747
- create_block_param("block", type: "T.nilable(T.proc.params(object: #{RelationClassName}).void)"),
928
+ RBI::KwOptParam.new("of", "1000"),
929
+ RBI::KwOptParam.new("start", "nil"),
930
+ RBI::KwOptParam.new("finish", "nil"),
931
+ RBI::KwOptParam.new("load", "false"),
932
+ RBI::KwOptParam.new("error_on_ignore", "nil"),
933
+ *(RBI::KwOptParam.new("order", ":asc") if order),
934
+ *(RBI::KwOptParam.new("use_ranges", "nil") if use_ranges),
935
+ RBI::BlockParam.new("block"),
748
936
  ],
749
- return_type: "T.nilable(::ActiveRecord::Batches::BatchEnumerator)",
750
937
  )
751
938
  end
752
939
  end
@@ -1,11 +1,7 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- begin
5
- require "active_record"
6
- rescue LoadError
7
- return
8
- end
4
+ return unless defined?(ActiveRecord::Base)
9
5
 
10
6
  require "tapioca/dsl/helpers/active_record_constants_helper"
11
7
 
@@ -1,11 +1,7 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- begin
5
- require "active_record"
6
- rescue LoadError
7
- return
8
- end
4
+ return unless defined?(ActiveRecord::Base)
9
5
 
10
6
  require "tapioca/dsl/helpers/active_record_constants_helper"
11
7
 
@@ -1,11 +1,7 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- begin
5
- require "active_record"
6
- rescue LoadError
7
- return
8
- end
4
+ return unless defined?(ActiveRecord::Base)
9
5
 
10
6
  require "tapioca/dsl/helpers/active_record_constants_helper"
11
7
 
@@ -1,13 +1,7 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- begin
5
- require "activerecord-typedstore"
6
- rescue LoadError
7
- # means ActiveRecord::TypedStore is not installed,
8
- # so let's not even define the compiler.
9
- return
10
- end
4
+ return unless defined?(ActiveRecord::Base) && defined?(ActiveRecord::TypedStore)
11
5
 
12
6
  module Tapioca
13
7
  module Dsl
@@ -1,11 +1,7 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- begin
5
- require "active_resource"
6
- rescue LoadError
7
- return
8
- end
4
+ return unless defined?(ActiveResource::Base)
9
5
 
10
6
  module Tapioca
11
7
  module Dsl
@@ -1,12 +1,7 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- begin
5
- require "active_storage"
6
- require "active_storage/reflection"
7
- rescue LoadError
8
- return
9
- end
4
+ return unless defined?(ActiveStorage::Reflection::ActiveRecordExtensions::ClassMethods)
10
5
 
11
6
  module Tapioca
12
7
  module Dsl
@@ -1,11 +1,7 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- begin
5
- require "active_support"
6
- rescue LoadError
7
- return
8
- end
4
+ return unless defined?(ActiveSupport::Concern)
9
5
 
10
6
  module Tapioca
11
7
  module Dsl
@@ -1,13 +1,7 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- begin
5
- require "active_support"
6
- # The following is needed due to https://github.com/rails/rails/pull/41610
7
- require "active_support/core_ext/module/delegation"
8
- rescue LoadError
9
- return
10
- end
4
+ return unless defined?(ActiveSupport::CurrentAttributes)
11
5
 
12
6
  module Tapioca
13
7
  module Dsl
@@ -122,17 +116,13 @@ module Tapioca
122
116
 
123
117
  sig { params(klass: RBI::Scope, method: String, class_method: T::Boolean).void }
124
118
  def generate_method(klass, method, class_method:)
125
- if method.end_with?("=")
126
- parameter = create_param("value", type: "T.untyped")
127
- klass.create_method(
128
- method,
129
- class_method: class_method,
130
- parameters: [parameter],
131
- return_type: "T.untyped",
132
- )
119
+ method_def = if class_method
120
+ constant.method(method)
133
121
  else
134
- klass.create_method(method, class_method: class_method, return_type: "T.untyped")
122
+ constant.instance_method(method)
135
123
  end
124
+
125
+ create_method_from_def(klass, method_def, class_method: class_method)
136
126
  end
137
127
  end
138
128
  end
@@ -1,11 +1,7 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- begin
5
- require "config"
6
- rescue LoadError
7
- return
8
- end
4
+ return unless defined?(Config) && defined?(Config::VERSION) && defined?(Config.const_name)
9
5
 
10
6
  module Tapioca
11
7
  module Dsl
@@ -1,11 +1,7 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- begin
5
- require "frozen_record"
6
- rescue LoadError
7
- return
8
- end
4
+ return unless defined?(FrozenRecord::Base)
9
5
 
10
6
  module Tapioca
11
7
  module Dsl
@@ -1,12 +1,8 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- begin
5
- gem("graphql", ">= 1.13")
6
- require "graphql"
7
- rescue LoadError
8
- return
9
- end
4
+ return unless defined?(GraphQL::Schema::InputObject)
5
+ return unless Gem::Requirement.new(">= 1.13").satisfied_by?(Gem::Version.new(GraphQL::VERSION))
10
6
 
11
7
  require "tapioca/dsl/helpers/graphql_type_helper"
12
8
 
@@ -1,12 +1,8 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- begin
5
- gem("graphql", ">= 1.13")
6
- require "graphql"
7
- rescue LoadError
8
- return
9
- end
4
+ return unless defined?(GraphQL::Schema::InputObject)
5
+ return unless Gem::Requirement.new(">= 1.13").satisfied_by?(Gem::Version.new(GraphQL::VERSION))
10
6
 
11
7
  require "tapioca/dsl/helpers/graphql_type_helper"
12
8
 
@@ -1,13 +1,7 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- begin
5
- require "identity_cache"
6
- rescue LoadError
7
- # means IdentityCache is not installed,
8
- # so let's not even define the compiler.
9
- return
10
- end
4
+ return unless defined?(ActiveRecord::Base) && defined?(IdentityCache::WithoutPrimaryIndex)
11
5
 
12
6
  require "tapioca/dsl/helpers/active_record_column_type_helper"
13
7
 
@@ -1,13 +1,7 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- begin
5
- require "json_api_client"
6
- rescue LoadError
7
- # means JsonApiClient is not installed,
8
- # so let's not even define the compiler.
9
- return
10
- end
4
+ return unless defined?(JsonApiClient::Resource)
11
5
 
12
6
  module Tapioca
13
7
  module Dsl