rails-on-sorbet 0.2.8 → 0.3.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8ed0619a2df969a26e1a4c8a393f0c939d6f5810754404bc7d65dae595f86b56
4
- data.tar.gz: 682c7f75757f90a583dac625a9b7a745f666d4893629b5ff78e1fbb3564d93f8
3
+ metadata.gz: 0d2e5584be831c2f9ee13193b7330f3c4fcfcb38e23b58e647e447ea44fba206
4
+ data.tar.gz: f1dcacdc4b00dd531400fb81b208e2ed0593f241156978adf8846c131c89cdfb
5
5
  SHA512:
6
- metadata.gz: fa387b998f9c63a795ed3f1849f83bf4909343c6c87ae865b16d747e7cc9dfa46ecab8e7e7d918213f2367c4c754f8759beca26f5a40594bcfe4972e5418925c
7
- data.tar.gz: 76311248119ffa6f7b17c3ae9a8219cfee17957f25d2fbc21864ebda0134c66eee9fda3d9d962aaf3f38a169e5a9348b0f66f2d91310be503491c594b49a4ba1
6
+ metadata.gz: 5065d66ccba78ecf89b3b0aa3acc1db333b7223d048b5fe6584170d8f87219d3e0cd9a20595b8cd115ab309aaf777ab0a3c16de21d82dd08b2bb1606145f29a1
7
+ data.tar.gz: 8054062e2ccb3ef943a08735ecb54358c901ace2b387cc6c25022062b0ccd9ede91ca11498f5e6726d2def2b4097930a35adfccc00ed5dd8c977d80e721bb112
data/CHANGELOG.md CHANGED
@@ -12,6 +12,20 @@ Add changes in new features here. Do not change the gem's version in pull/merge
12
12
  ### Changes
13
13
  -
14
14
 
15
+ ## [0.3.1] - 20.10.2025
16
+
17
+ [Diff](https://github.com/espago/rails-on-sorbet/compare/v0.3.0...v0.3.1)
18
+
19
+ ### Changes
20
+ - Fix `Tapioca::Compilers::RailsOnSorbetActiveRecordRelations` and `TypedRelation` definitions
21
+
22
+ ## [0.3.0] - 20.10.2025
23
+
24
+ [Diff](https://github.com/espago/rails-on-sorbet/compare/v0.2.8...v0.3.0)
25
+
26
+ ### Changes
27
+ - Add `TypedRelation` and `TypedAssociation` for better ActiveRecord::Relation sorbet handling
28
+
15
29
  ## [0.2.8] - 16.10.2025
16
30
 
17
31
  [Diff](https://github.com/espago/rails-on-sorbet/compare/v0.2.7...v0.2.8)
data/README.md CHANGED
@@ -85,6 +85,62 @@ m = Map(params) #=> Map[String, untyped]
85
85
  foo(m) # OK
86
86
  ```
87
87
 
88
+ ### TypedRelation
89
+
90
+ Sorbet lacks proper generic handling of `ActiveRecord::Relation`.
91
+ The class itself is not generic and tapioca generates a bunch of classes like `X::PrivateRelation`, `X::PrivateAssociationRelation`, `X::PrivateCollectionProxy` per model but these classes have no common generic ancestors which makes them incredibly finnicky to work with.
92
+
93
+ Because of that we introduced a bunch of interfaces:
94
+ - `TypedRelation` is included by per-model classes like `X::PrivateRelation`
95
+ - `TypedAssociation::Relation` is included by per-model classes like `X::PrivateAssociationRelation`
96
+ - `TypedAssociation::CollectionProxy` is included by per-model classes like `X::PrivateCollectionProxy`
97
+
98
+ Example:
99
+ ```rb
100
+ class Foo < ActiveRecord::Base
101
+ has_many :bars
102
+ end
103
+
104
+ foo = Foo.new
105
+ foo.bars #=> Bar::PrivateCollectionProxy
106
+
107
+ #: (TypedAssociation::CollectionProxy[Bar]) -> void
108
+ def do_smth(rel); end
109
+
110
+ do_smth(foo.bars) # ok!
111
+ ```
112
+
113
+ One common use case is working on child/parent model associations.
114
+
115
+ ```rb
116
+ class Foo < ActiveRecord::Base
117
+ belongs_to :user
118
+ end
119
+
120
+ class Bar < Foo
121
+ belongs_to :manager
122
+ end
123
+
124
+ class User < ActiveRecord::Base
125
+ has_many :foos
126
+ end
127
+
128
+ class Manager < ActiveRecord::Base
129
+ has_many :bars
130
+ end
131
+
132
+ #: (TypedAssociation::CollectionProxy[Foo]) -> void
133
+ def do_smth_on_foos(rel); end
134
+
135
+ user = User.new
136
+ user.foos #=> Foo::PrivateCollectionProxy
137
+ do_smth_on_foos(user.foos) # ok!
138
+
139
+ user = Manager.new
140
+ user.bars #=> Bar::PrivateCollectionProxy
141
+ do_smth_on_foos(user.bars) # ok!
142
+ ```
143
+
88
144
  ### ActiveRecord::Base::alias_association
89
145
 
90
146
  This gem adds a new method called `alias_association` on ActiveRecord classes.
@@ -92,13 +148,13 @@ It lets you define aliases for getters and setters of `belongs_to` and `has_one`
92
148
 
93
149
  Example:
94
150
  ```rb
95
- class Foo < ApplicationRecord
96
- belongs_to :user
97
- alias_association :owner, :user
98
- end
151
+ class Foo < ApplicationRecord
152
+ belongs_to :user
153
+ alias_association :owner, :user
154
+ end
99
155
 
100
- f = Foo.last
101
- f.owner == f.user #=> true
156
+ f = Foo.last
157
+ f.owner == f.user #=> true
102
158
  ```
103
159
 
104
160
  ### Rails::On::Sorbet::CurrentAttributes
@@ -0,0 +1,58 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ require 'action_controller'
5
+ require 'active_support'
6
+
7
+ # Represents a `X::PrivateRelation` tapioca generated class, where `X` is an ActiveRecord model.
8
+ module TypedRelation
9
+ extend T::Generic
10
+
11
+ class << self
12
+ def GroupChain(val) = val # rubocop:disable Naming/MethodName
13
+ def WhereChain(val) = val # rubocop:disable Naming/MethodName
14
+ end
15
+
16
+ module GroupChain
17
+ extend T::Generic
18
+ include TypedRelation
19
+ end
20
+
21
+ module WhereChain
22
+ extend T::Generic
23
+ end
24
+ end
25
+
26
+ def TypedRelation(val) = val # rubocop:disable Style/TopLevelMethodDefinition,Naming/MethodName
27
+
28
+ # A namespace for typed ActiveRecord association objects.
29
+ module TypedAssociation
30
+ class << self
31
+ def Relation(val) = val # rubocop:disable Naming/MethodName
32
+ def CollectionProxy(val) = val # rubocop:disable Naming/MethodName
33
+ end
34
+
35
+ # Represents a `X::PrivateAssociationRelation` tapioca generated class, where `X` is an ActiveRecord model.
36
+ module Relation
37
+ extend T::Generic
38
+
39
+ class << self
40
+ def GroupChain(val) = val # rubocop:disable Naming/MethodName
41
+ def WhereChain(val) = val # rubocop:disable Naming/MethodName
42
+ def CollectionProxy(val) = val # rubocop:disable Naming/MethodName
43
+ end
44
+
45
+ module GroupChain
46
+ extend T::Generic
47
+ include Relation
48
+ end
49
+
50
+ module WhereChain
51
+ extend T::Generic
52
+ end
53
+ end
54
+
55
+ module CollectionProxy
56
+ extend T::Generic
57
+ end
58
+ end
@@ -3,7 +3,7 @@
3
3
  module Rails
4
4
  module On
5
5
  module Sorbet
6
- VERSION = '0.2.8'
6
+ VERSION = '0.3.1'
7
7
  end
8
8
  end
9
9
  end
@@ -0,0 +1,49 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module Tapioca
5
+ module Compilers
6
+ # Creates .rbi files with types for classes that use ActiveRecord relations
7
+ #: [ConstantType < singleton(::ActiveRecord::Base)]
8
+ class RailsOnSorbetActiveRecordRelations < Tapioca::Dsl::Compiler
9
+ class << self
10
+ # @override
11
+ #: -> T::Enumerable[Module]
12
+ def gather_constants
13
+ all_classes.select do |klass|
14
+ klass < ::ActiveRecord::Base
15
+ end
16
+ end
17
+ end
18
+
19
+ # @override
20
+ #: -> void
21
+ def decorate
22
+ root.create_path(constant) do |klass|
23
+ private_relation = klass.create_class('PrivateRelation')
24
+ private_relation.create_include('::TypedRelation')
25
+
26
+ private_relation_group_chain = klass.create_class('PrivateRelationGroupChain')
27
+ private_relation_group_chain.create_include('::TypedRelation::GroupChain')
28
+
29
+ private_relation_where_chain = klass.create_class('PrivateRelationWhereChain')
30
+ private_relation_where_chain.create_include('::TypedRelation::WhereChain')
31
+
32
+
33
+ private_association_relation = klass.create_class('PrivateAssociationRelation')
34
+ private_association_relation.create_include('::TypedAssociation::Relation')
35
+
36
+ private_relation_group_chain = klass.create_class('PrivateAssociationRelationGroupChain')
37
+ private_relation_group_chain.create_include('::TypedAssociation::Relation::GroupChain')
38
+
39
+ private_relation_where_chain = klass.create_class('PrivateAssociationRelationWhereChain')
40
+ private_relation_where_chain.create_include('::TypedAssociation::Relation::WhereChain')
41
+
42
+ private_collection_proxy = klass.create_class('PrivateCollectionProxy')
43
+ private_collection_proxy.create_include('::TypedAssociation::CollectionProxy')
44
+ end
45
+ end
46
+
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,939 @@
1
+ # typed: false
2
+
3
+ #: (ActiveRecord::Relation) -> TypedRelation[untyped]
4
+ def TypedRelation(val); end
5
+
6
+ # @abstract
7
+ module TypedCommonRelationMethods
8
+ Elem = type_member(:out)
9
+
10
+ # START CommonRelationMethods
11
+
12
+ sig { abstract.returns(T::Array[Elem]) }
13
+ def to_a; end
14
+
15
+ sig { abstract.returns(T::Array[Elem]) }
16
+ def to_ary; end
17
+
18
+ sig do
19
+ abstract.params(
20
+ block: T.nilable(T.proc.params(record: Elem).returns(T.untyped))
21
+ ).returns(T::Boolean)
22
+ end
23
+ def any?(&block); end
24
+
25
+ sig { abstract.params(column_name: T.any(String, Symbol)).returns(T.any(Integer, Float, BigDecimal)) }
26
+ def average(column_name); end
27
+
28
+ sig do
29
+ params(
30
+ block: T.nilable(T.proc.params(object: Elem).void)
31
+ ).returns(Elem)
32
+ end
33
+ sig do
34
+ params(
35
+ attributes: T::Array[T.untyped],
36
+ block: T.nilable(T.proc.params(object: Elem).void)
37
+ ).returns(T::Array[Elem])
38
+ end
39
+ sig do
40
+ params(
41
+ attributes: T.untyped,
42
+ block: T.nilable(T.proc.params(object: Elem).void)
43
+ ).returns(Elem)
44
+ end
45
+ def build(attributes = nil, &block); end
46
+
47
+ sig { abstract.params(operation: Symbol, column_name: T.any(String, Symbol)).returns(T.any(Integer, Float, BigDecimal)) }
48
+ def calculate(operation, column_name); end
49
+
50
+ sig { params(column_name: T.nilable(T.any(String, Symbol))).returns(Integer) }
51
+ sig do
52
+ params(
53
+ column_name: NilClass,
54
+ block: T.proc.params(object: Elem).void
55
+ ).returns(Integer)
56
+ end
57
+ def count(column_name = nil, &block); end
58
+
59
+ sig do
60
+ params(
61
+ block: T.nilable(T.proc.params(object: Elem).void)
62
+ ).returns(Elem)
63
+ end
64
+ sig do
65
+ params(
66
+ attributes: T::Array[T.untyped],
67
+ block: T.nilable(T.proc.params(object: Elem).void)
68
+ ).returns(T::Array[Elem])
69
+ end
70
+ sig do
71
+ params(
72
+ attributes: T.untyped,
73
+ block: T.nilable(T.proc.params(object: Elem).void)
74
+ ).returns(Elem)
75
+ end
76
+ def create(attributes = nil, &block); end
77
+
78
+ sig do
79
+ params(
80
+ block: T.nilable(T.proc.params(object: Elem).void)
81
+ ).returns(Elem)
82
+ end
83
+ sig do
84
+ params(
85
+ attributes: T::Array[T.untyped],
86
+ block: T.nilable(T.proc.params(object: Elem).void)
87
+ ).returns(T::Array[Elem])
88
+ end
89
+ sig do
90
+ params(
91
+ attributes: T.untyped,
92
+ block: T.nilable(T.proc.params(object: Elem).void)
93
+ ).returns(Elem)
94
+ end
95
+ def create!(attributes = nil, &block); end
96
+
97
+ sig do
98
+ params(
99
+ attributes: T::Array[T.untyped],
100
+ block: T.nilable(T.proc.params(object: Elem).void)
101
+ ).returns(T::Array[Elem])
102
+ end
103
+ sig do
104
+ params(
105
+ attributes: T.untyped,
106
+ block: T.nilable(T.proc.params(object: Elem).void)
107
+ ).returns(Elem)
108
+ end
109
+ def create_or_find_by(attributes, &block); end
110
+
111
+ sig do
112
+ params(
113
+ attributes: T::Array[T.untyped],
114
+ block: T.nilable(T.proc.params(object: Elem).void)
115
+ ).returns(T::Array[Elem])
116
+ end
117
+ sig do
118
+ params(
119
+ attributes: T.untyped,
120
+ block: T.nilable(T.proc.params(object: Elem).void)
121
+ ).returns(Elem)
122
+ end
123
+ def create_or_find_by!(attributes, &block); end
124
+
125
+ sig { returns(T::Array[Elem]) }
126
+ def destroy_all; end
127
+
128
+ sig { params(conditions: T.untyped).returns(T::Boolean) }
129
+ def exists?(conditions = :none); end
130
+
131
+ sig { returns(T.nilable(Elem)) }
132
+ def fifth; end
133
+
134
+ sig { returns(Elem) }
135
+ def fifth!; end
136
+
137
+ sig do
138
+ params(
139
+ args: T.any(String, Symbol, ::ActiveSupport::Multibyte::Chars, T::Boolean, BigDecimal, Numeric, ::ActiveRecord::Type::Binary::Data, ::ActiveRecord::Type::Time::Value, Date, Time, ::ActiveSupport::Duration, T::Class[T.anything])
140
+ ).returns(Elem)
141
+ end
142
+ sig do
143
+ params(
144
+ args: T::Array[T.any(String, Symbol, ::ActiveSupport::Multibyte::Chars, T::Boolean, BigDecimal, Numeric, ::ActiveRecord::Type::Binary::Data, ::ActiveRecord::Type::Time::Value, Date, Time, ::ActiveSupport::Duration, T::Class[T.anything])]
145
+ ).returns(T::Enumerable[Elem])
146
+ end
147
+ sig do
148
+ params(
149
+ args: NilClass,
150
+ block: T.proc.params(object: Elem).void
151
+ ).returns(T.nilable(Elem))
152
+ end
153
+ def find(args = nil, &block); end
154
+
155
+ sig { params(args: T.untyped).returns(T.nilable(Elem)) }
156
+ def find_by(*args); end
157
+
158
+ sig { params(args: T.untyped).returns(Elem) }
159
+ def find_by!(*args); end
160
+
161
+ sig do
162
+ params(
163
+ start: T.untyped,
164
+ finish: T.untyped,
165
+ batch_size: Integer,
166
+ error_on_ignore: T.untyped,
167
+ order: Symbol,
168
+ block: T.proc.params(object: Elem).void
169
+ ).void
170
+ end
171
+ sig do
172
+ params(
173
+ start: T.untyped,
174
+ finish: T.untyped,
175
+ batch_size: Integer,
176
+ error_on_ignore: T.untyped,
177
+ order: Symbol
178
+ ).returns(T::Enumerator[Elem])
179
+ end
180
+ def find_each(start: nil, finish: nil, batch_size: 1000, error_on_ignore: nil, order: :asc, &block); end
181
+
182
+ sig do
183
+ params(
184
+ start: T.untyped,
185
+ finish: T.untyped,
186
+ batch_size: Integer,
187
+ error_on_ignore: T.untyped,
188
+ order: Symbol,
189
+ block: T.proc.params(object: T::Array[Elem]).void
190
+ ).void
191
+ end
192
+ sig do
193
+ params(
194
+ start: T.untyped,
195
+ finish: T.untyped,
196
+ batch_size: Integer,
197
+ error_on_ignore: T.untyped,
198
+ order: Symbol
199
+ ).returns(T::Enumerator[T::Enumerator[Elem]])
200
+ end
201
+ def find_in_batches(start: nil, finish: nil, batch_size: 1000, error_on_ignore: nil, order: :asc, &block); end
202
+
203
+ sig do
204
+ params(
205
+ attributes: T::Array[T.untyped],
206
+ block: T.nilable(T.proc.params(object: Elem).void)
207
+ ).returns(T::Array[Elem])
208
+ end
209
+ sig do
210
+ params(
211
+ attributes: T.untyped,
212
+ block: T.nilable(T.proc.params(object: Elem).void)
213
+ ).returns(Elem)
214
+ end
215
+ def find_or_create_by(attributes, &block); end
216
+
217
+ sig do
218
+ params(
219
+ attributes: T::Array[T.untyped],
220
+ block: T.nilable(T.proc.params(object: Elem).void)
221
+ ).returns(T::Array[Elem])
222
+ end
223
+ sig do
224
+ params(
225
+ attributes: T.untyped,
226
+ block: T.nilable(T.proc.params(object: Elem).void)
227
+ ).returns(Elem)
228
+ end
229
+ def find_or_create_by!(attributes, &block); end
230
+
231
+ sig do
232
+ params(
233
+ attributes: T::Array[T.untyped],
234
+ block: T.nilable(T.proc.params(object: Elem).void)
235
+ ).returns(T::Array[Elem])
236
+ end
237
+ sig do
238
+ params(
239
+ attributes: T.untyped,
240
+ block: T.nilable(T.proc.params(object: Elem).void)
241
+ ).returns(Elem)
242
+ end
243
+ def find_or_initialize_by(attributes, &block); end
244
+
245
+ sig do
246
+ abstract.params(
247
+ signed_id: T.untyped,
248
+ purpose: T.untyped
249
+ ).returns(T.nilable(Elem))
250
+ end
251
+ def find_signed(signed_id, purpose: nil); end
252
+
253
+ sig { abstract.params(signed_id: T.untyped, purpose: T.untyped).returns(Elem) }
254
+ def find_signed!(signed_id, purpose: nil); end
255
+
256
+ sig { abstract.params(arg: T.untyped, args: T.untyped).returns(Elem) }
257
+ def find_sole_by(arg, *args); end
258
+
259
+ sig { returns(T.nilable(Elem)) }
260
+ sig { params(limit: Integer).returns(T::Array[Elem]) }
261
+ def first(limit = nil); end
262
+
263
+ sig { abstract.returns(Elem) }
264
+ def first!; end
265
+
266
+ sig { abstract.returns(T.nilable(Elem)) }
267
+ def forty_two; end
268
+
269
+ sig { abstract.returns(Elem) }
270
+ def forty_two!; end
271
+
272
+ sig { abstract.returns(T.nilable(Elem)) }
273
+ def fourth; end
274
+
275
+ sig { abstract.returns(Elem) }
276
+ def fourth!; end
277
+
278
+ sig { abstract.returns(Array) }
279
+ def ids; end
280
+
281
+ sig do
282
+ params(
283
+ of: Integer,
284
+ start: T.untyped,
285
+ finish: T.untyped,
286
+ load: T.untyped,
287
+ error_on_ignore: T.untyped,
288
+ order: Symbol,
289
+ use_ranges: T.untyped,
290
+ block: T.proc.params(object: T.untyped).void
291
+ ).void
292
+ end
293
+ sig do
294
+ params(
295
+ of: Integer,
296
+ start: T.untyped,
297
+ finish: T.untyped,
298
+ load: T.untyped,
299
+ error_on_ignore: T.untyped,
300
+ order: Symbol,
301
+ use_ranges: T.untyped
302
+ ).returns(::ActiveRecord::Batches::BatchEnumerator)
303
+ end
304
+ def in_batches(of: 1000, start: nil, finish: nil, load: false, error_on_ignore: nil, order: :asc, use_ranges: nil, &block); end
305
+
306
+ sig { abstract.params(record: T.untyped).returns(T::Boolean) }
307
+ def include?(record); end
308
+
309
+ sig { returns(T.nilable(Elem)) }
310
+ sig { params(limit: Integer).returns(T::Array[Elem]) }
311
+ def last(limit = nil); end
312
+
313
+ sig { returns(Elem) }
314
+ def last!; end
315
+
316
+ sig do
317
+ abstract.params(
318
+ block: T.nilable(T.proc.params(record: Elem).returns(T.untyped))
319
+ ).returns(T::Boolean)
320
+ end
321
+ def many?(&block); end
322
+
323
+ sig { abstract.params(column_name: T.any(String, Symbol)).returns(T.untyped) }
324
+ def maximum(column_name); end
325
+
326
+ sig { abstract.params(record: T.untyped).returns(T::Boolean) }
327
+ def member?(record); end
328
+
329
+ sig { abstract.params(column_name: T.any(String, Symbol)).returns(T.untyped) }
330
+ def minimum(column_name); end
331
+
332
+ sig do
333
+ params(
334
+ block: T.nilable(T.proc.params(object: Elem).void)
335
+ ).returns(Elem)
336
+ end
337
+ sig do
338
+ params(
339
+ attributes: T::Array[T.untyped],
340
+ block: T.nilable(T.proc.params(object: Elem).void)
341
+ ).returns(T::Array[Elem])
342
+ end
343
+ sig do
344
+ params(
345
+ attributes: T.untyped,
346
+ block: T.nilable(T.proc.params(object: Elem).void)
347
+ ).returns(Elem)
348
+ end
349
+ def new(attributes = nil, &block); end
350
+
351
+ sig do
352
+ abstract.params(
353
+ block: T.nilable(T.proc.params(record: Elem).returns(T.untyped))
354
+ ).returns(T::Boolean)
355
+ end
356
+ def none?(&block); end
357
+
358
+ sig do
359
+ abstract.params(
360
+ block: T.nilable(T.proc.params(record: Elem).returns(T.untyped))
361
+ ).returns(T::Boolean)
362
+ end
363
+ def one?(&block); end
364
+
365
+ sig { abstract.params(column_names: T.untyped).returns(T.untyped) }
366
+ def pick(*column_names); end
367
+
368
+ sig { abstract.params(column_names: T.untyped).returns(T.untyped) }
369
+ def pluck(*column_names); end
370
+
371
+ sig { abstract.returns(T.nilable(Elem)) }
372
+ def second; end
373
+
374
+ sig { abstract.returns(Elem) }
375
+ def second!; end
376
+
377
+ sig { abstract.returns(T.nilable(Elem)) }
378
+ def second_to_last; end
379
+
380
+ sig { abstract.returns(Elem) }
381
+ def second_to_last!; end
382
+
383
+ sig { abstract.returns(Elem) }
384
+ def sole; end
385
+
386
+ sig { params(initial_value_or_column: T.untyped).returns(T.any(Integer, Float, BigDecimal)) }
387
+ sig do
388
+ type_parameters(:U)
389
+ .params(
390
+ initial_value_or_column: T.nilable(T.type_parameter(:U)),
391
+ block: T.proc.params(object: Elem).returns(T.type_parameter(:U))
392
+ ).returns(T.type_parameter(:U))
393
+ end
394
+ def sum(initial_value_or_column = nil, &block); end
395
+
396
+ sig { returns(T.nilable(Elem)) }
397
+ sig { params(limit: Integer).returns(T::Array[Elem]) }
398
+ def take(limit = nil); end
399
+
400
+ sig { abstract.returns(Elem) }
401
+ def take!; end
402
+
403
+ sig { abstract.returns(T.nilable(Elem)) }
404
+ def third; end
405
+
406
+ sig { abstract.returns(Elem) }
407
+ def third!; end
408
+
409
+ sig { abstract.returns(T.nilable(Elem)) }
410
+ def third_to_last; end
411
+
412
+ sig { abstract.returns(Elem) }
413
+ def third_to_last!; end
414
+
415
+ # END CommonRelationMethods
416
+ end
417
+
418
+ # @abstract
419
+ module TypedRelation
420
+ Elem = type_member(:out)
421
+
422
+ class << self
423
+ #: (ActiveRecord::Relation) -> GroupChain[untyped]
424
+ def GroupChain(val); end
425
+ #: (ActiveRecord::QueryMethods::WhereChain) -> WhereChain[untyped]
426
+ def WhereChain(val); end
427
+ end
428
+
429
+ # @abstract
430
+ module GroupChain
431
+ include TypedRelation
432
+
433
+ Elem = type_member(:out)
434
+
435
+ sig { abstract.params(column_name: T.any(String, Symbol)).returns(T::Hash[T.untyped, T.any(Integer, Float, BigDecimal)]) }
436
+ def average(column_name); end
437
+
438
+ sig do
439
+ abstract.params(
440
+ operation: Symbol,
441
+ column_name: T.any(String, Symbol)
442
+ ).returns(T::Hash[T.untyped, T.any(Integer, Float, BigDecimal)])
443
+ end
444
+ def calculate(operation, column_name); end
445
+
446
+ sig { abstract.params(column_name: T.untyped).returns(T::Hash[T.untyped, Integer]) }
447
+ def count(column_name = nil); end
448
+
449
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
450
+ def having(*args, &blk); end
451
+
452
+ sig { abstract.params(column_name: T.any(String, Symbol)).returns(T::Hash[T.untyped, T.untyped]) }
453
+ def maximum(column_name); end
454
+
455
+ sig { abstract.params(column_name: T.any(String, Symbol)).returns(T::Hash[T.untyped, T.untyped]) }
456
+ def minimum(column_name); end
457
+
458
+ sig { returns(T::Hash[T.untyped, Integer]) }
459
+ def size; end
460
+
461
+ sig do
462
+ abstract.params(
463
+ column_name: T.nilable(T.any(String, Symbol)),
464
+ block: T.nilable(T.proc.params(record: T.untyped).returns(T.untyped))
465
+ ).returns(T::Hash[T.untyped, T.any(Integer, Float, BigDecimal)])
466
+ end
467
+ def sum(column_name = nil, &block); end
468
+ end
469
+
470
+ # @abstract
471
+ module WhereChain
472
+ Elem = type_member(:out)
473
+
474
+ sig { abstract.params(args: T.untyped).returns(TypedRelation[Elem]) }
475
+ def associated(*args); end
476
+
477
+ sig { abstract.params(args: T.untyped).returns(TypedRelation[Elem]) }
478
+ def missing(*args); end
479
+
480
+ sig { abstract.params(opts: T.untyped, rest: T.untyped).returns(TypedRelation[Elem]) }
481
+ def not(opts, *rest); end
482
+ end
483
+
484
+ include TypedCommonRelationMethods
485
+
486
+ # START GeneratedRelationMethods
487
+
488
+ sig { abstract.returns(T.self_type) }
489
+ def all; end
490
+
491
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
492
+ def and(*args, &blk); end
493
+
494
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
495
+ def annotate(*args, &blk); end
496
+
497
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
498
+ def arel_columns(*args, &blk); end
499
+
500
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
501
+ def create_with(*args, &blk); end
502
+
503
+ sig { abstract.params(value: T::Boolean).returns(T.self_type) }
504
+ def distinct(value = true); end
505
+
506
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
507
+ def eager_load(*args, &blk); end
508
+
509
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
510
+ def except(*args, &blk); end
511
+
512
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
513
+ def excluding(*args, &blk); end
514
+
515
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
516
+ def extending(*args, &blk); end
517
+
518
+ sig { abstract.params(association: Symbol).returns(T::Array[T.untyped]) }
519
+ def extract_associated(association); end
520
+
521
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
522
+ def from(*args, &blk); end
523
+
524
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(GroupChain[Elem]) }
525
+ def group(*args, &blk); end
526
+
527
+ sig { params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
528
+ def having(*args, &blk); end
529
+
530
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
531
+ def in_order_of(*args, &blk); end
532
+
533
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
534
+ def includes(*args, &blk); end
535
+
536
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
537
+ def invert_where(*args, &blk); end
538
+
539
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
540
+ def joins(*args, &blk); end
541
+
542
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
543
+ def left_joins(*args, &blk); end
544
+
545
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
546
+ def left_outer_joins(*args, &blk); end
547
+
548
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
549
+ def limit(*args, &blk); end
550
+
551
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
552
+ def lock(*args, &blk); end
553
+
554
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
555
+ def merge(*args, &blk); end
556
+
557
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
558
+ def none(*args, &blk); end
559
+
560
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
561
+ def null_relation?(*args, &blk); end
562
+
563
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
564
+ def offset(*args, &blk); end
565
+
566
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
567
+ def only(*args, &blk); end
568
+
569
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
570
+ def optimizer_hints(*args, &blk); end
571
+
572
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
573
+ def or(*args, &blk); end
574
+
575
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
576
+ def order(*args, &blk); end
577
+
578
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
579
+ def preload(*args, &blk); end
580
+
581
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
582
+ def readonly(*args, &blk); end
583
+
584
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
585
+ def references(*args, &blk); end
586
+
587
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
588
+ def regroup(*args, &blk); end
589
+
590
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
591
+ def reorder(*args, &blk); end
592
+
593
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
594
+ def reselect(*args, &blk); end
595
+
596
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
597
+ def reverse_order(*args, &blk); end
598
+
599
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
600
+ def rewhere(*args, &blk); end
601
+
602
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
603
+ def sanitize_forbidden_attributes(*args, &blk); end
604
+
605
+ sig { params(args: T.untyped).returns(T.self_type) }
606
+ sig do
607
+ params(
608
+ blk: T.proc.params(record: Elem).returns(BasicObject)
609
+ ).returns(T::Array[Elem])
610
+ end
611
+ def select(*args, &blk); end
612
+
613
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
614
+ def strict_loading(*args, &blk); end
615
+
616
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
617
+ def structurally_compatible?(*args, &blk); end
618
+
619
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
620
+ def uniq!(*args, &blk); end
621
+
622
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
623
+ def unscope(*args, &blk); end
624
+
625
+ sig { returns(WhereChain[Elem]) }
626
+ sig { params(args: T.untyped).returns(T.self_type) }
627
+ def where(*args); end
628
+
629
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
630
+ def with(*args, &blk); end
631
+
632
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
633
+ def with_recursive(*args, &blk); end
634
+
635
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
636
+ def without(*args, &blk); end
637
+ end
638
+
639
+ # @abstract
640
+ module TypedGeneratedAssociationRelationMethods
641
+ Elem = type_member(:out)
642
+
643
+ sig { abstract.returns(T::Array[Elem]) }
644
+ def to_a; end
645
+
646
+ sig { abstract.returns(T::Array[Elem]) }
647
+ def to_ary; end
648
+
649
+ sig { abstract.returns(T.self_type) }
650
+ def all; end
651
+
652
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
653
+ def and(*args, &blk); end
654
+
655
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
656
+ def annotate(*args, &blk); end
657
+
658
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
659
+ def arel_columns(*args, &blk); end
660
+
661
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
662
+ def create_with(*args, &blk); end
663
+
664
+ sig { abstract.params(value: T::Boolean).returns(T.self_type) }
665
+ def distinct(value = true); end
666
+
667
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
668
+ def eager_load(*args, &blk); end
669
+
670
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
671
+ def except(*args, &blk); end
672
+
673
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
674
+ def excluding(*args, &blk); end
675
+
676
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
677
+ def extending(*args, &blk); end
678
+
679
+ sig { abstract.params(association: Symbol).returns(T::Array[T.untyped]) }
680
+ def extract_associated(association); end
681
+
682
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
683
+ def from(*args, &blk); end
684
+
685
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(TypedAssociation::Relation::GroupChain[Elem]) }
686
+ def group(*args, &blk); end
687
+
688
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
689
+ def having(*args, &blk); end
690
+
691
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
692
+ def in_order_of(*args, &blk); end
693
+
694
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
695
+ def includes(*args, &blk); end
696
+
697
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
698
+ def invert_where(*args, &blk); end
699
+
700
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
701
+ def joins(*args, &blk); end
702
+
703
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
704
+ def left_joins(*args, &blk); end
705
+
706
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
707
+ def left_outer_joins(*args, &blk); end
708
+
709
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
710
+ def limit(*args, &blk); end
711
+
712
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
713
+ def lock(*args, &blk); end
714
+
715
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
716
+ def merge(*args, &blk); end
717
+
718
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
719
+ def none(*args, &blk); end
720
+
721
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
722
+ def null_relation?(*args, &blk); end
723
+
724
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
725
+ def offset(*args, &blk); end
726
+
727
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
728
+ def only(*args, &blk); end
729
+
730
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
731
+ def optimizer_hints(*args, &blk); end
732
+
733
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
734
+ def or(*args, &blk); end
735
+
736
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
737
+ def order(*args, &blk); end
738
+
739
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
740
+ def preload(*args, &blk); end
741
+
742
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
743
+ def readonly(*args, &blk); end
744
+
745
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
746
+ def references(*args, &blk); end
747
+
748
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
749
+ def regroup(*args, &blk); end
750
+
751
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
752
+ def reorder(*args, &blk); end
753
+
754
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
755
+ def reselect(*args, &blk); end
756
+
757
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
758
+ def reverse_order(*args, &blk); end
759
+
760
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
761
+ def rewhere(*args, &blk); end
762
+
763
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
764
+ def sanitize_forbidden_attributes(*args, &blk); end
765
+
766
+ sig { params(args: T.untyped).returns(T.self_type) }
767
+ sig do
768
+ params(
769
+ blk: T.proc.params(record: Elem).returns(BasicObject)
770
+ ).returns(T::Array[Elem])
771
+ end
772
+ def select(*args, &blk); end
773
+
774
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
775
+ def strict_loading(*args, &blk); end
776
+
777
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
778
+ def structurally_compatible?(*args, &blk); end
779
+
780
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
781
+ def uniq!(*args, &blk); end
782
+
783
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
784
+ def unscope(*args, &blk); end
785
+
786
+ sig { returns(TypedAssociation::Relation::WhereChain[Elem]) }
787
+ sig { params(args: T.untyped).returns(T.self_type) }
788
+ def where(*args); end
789
+
790
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
791
+ def with(*args, &blk); end
792
+
793
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
794
+ def with_recursive(*args, &blk); end
795
+
796
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
797
+ def without(*args, &blk); end
798
+ end
799
+
800
+ module TypedAssociation
801
+ class << self
802
+ #: (::ActiveRecord::Relation) -> Relation[untyped]
803
+ def Relation(val); end
804
+ #: (::ActiveRecord::Associations::CollectionProxy) -> CollectionProxy[untyped]
805
+ def CollectionProxy(val); end
806
+ end
807
+
808
+ # @abstract
809
+ module Relation
810
+ include TypedCommonRelationMethods
811
+ include TypedGeneratedAssociationRelationMethods
812
+
813
+ Elem = type_member(:out)
814
+
815
+ class << self
816
+ #: (ActiveRecord::Relation) -> GroupChain[untyped]
817
+ def GroupChain(val); end
818
+ #: (ActiveRecord::QueryMethods::WhereChain) -> WhereChain[untyped]
819
+ def WhereChain(val); end
820
+ end
821
+
822
+ # @abstract
823
+ module WhereChain
824
+ Elem = type_member(:out)
825
+
826
+ sig { abstract.params(args: T.untyped).returns(Relation[Elem]) }
827
+ def associated(*args); end
828
+
829
+ sig { abstract.params(args: T.untyped).returns(Relation[Elem]) }
830
+ def missing(*args); end
831
+
832
+ sig { abstract.params(opts: T.untyped, rest: T.untyped).returns(Relation[Elem]) }
833
+ def not(opts, *rest); end
834
+ end
835
+
836
+ # @abstract
837
+ module GroupChain
838
+ include Relation
839
+
840
+ Elem = type_member(:out)
841
+
842
+ sig { abstract.params(column_name: T.any(String, Symbol)).returns(T::Hash[T.untyped, T.any(Integer, Float, BigDecimal)]) }
843
+ def average(column_name); end
844
+
845
+ sig do
846
+ abstract.params(
847
+ operation: Symbol,
848
+ column_name: T.any(String, Symbol)
849
+ ).returns(T::Hash[T.untyped, T.any(Integer, Float, BigDecimal)])
850
+ end
851
+ def calculate(operation, column_name); end
852
+
853
+ sig { abstract.params(column_name: T.untyped).returns(T::Hash[T.untyped, Integer]) }
854
+ def count(column_name = nil); end
855
+
856
+ sig { abstract.params(args: T.untyped, blk: T.untyped).returns(T.self_type) }
857
+ def having(*args, &blk); end
858
+
859
+ sig { abstract.params(column_name: T.any(String, Symbol)).returns(T::Hash[T.untyped, T.untyped]) }
860
+ def maximum(column_name); end
861
+
862
+ sig { abstract.params(column_name: T.any(String, Symbol)).returns(T::Hash[T.untyped, T.untyped]) }
863
+ def minimum(column_name); end
864
+
865
+ sig { abstract.returns(T::Hash[T.untyped, Integer]) }
866
+ def size; end
867
+
868
+ sig do
869
+ abstract.params(
870
+ column_name: T.nilable(T.any(String, Symbol)),
871
+ block: T.nilable(T.proc.params(record: T.untyped).returns(T.untyped))
872
+ ).returns(T::Hash[T.untyped, T.any(Integer, Float, BigDecimal)])
873
+ end
874
+ def sum(column_name = nil, &block); end
875
+ end
876
+ end
877
+
878
+ # @abstract
879
+ module CollectionProxy
880
+ include TypedCommonRelationMethods
881
+ include TypedGeneratedAssociationRelationMethods
882
+
883
+ Elem = type_member(:out)
884
+
885
+ sig do
886
+ abstract.params(
887
+ records: T.any(Elem, T::Enumerable[T.any(Elem, T::Enumerable[Elem])])
888
+ ).returns(T.self_type)
889
+ end
890
+ def <<(*records); end
891
+
892
+ sig do
893
+ abstract.params(
894
+ records: T.any(Elem, T::Enumerable[T.any(Elem, T::Enumerable[Elem])])
895
+ ).returns(T.self_type)
896
+ end
897
+ def append(*records); end
898
+
899
+ sig { abstract.returns(T.self_type) }
900
+ def clear; end
901
+
902
+ sig do
903
+ abstract.params(
904
+ records: T.any(Elem, T::Enumerable[T.any(Elem, T::Enumerable[Elem])])
905
+ ).returns(T.self_type)
906
+ end
907
+ def concat(*records); end
908
+
909
+ sig { returns(T::Array[Elem]) }
910
+ def load_target; end
911
+
912
+ sig do
913
+ abstract.params(
914
+ records: T.any(Elem, T::Enumerable[T.any(Elem, T::Enumerable[Elem])])
915
+ ).returns(T.self_type)
916
+ end
917
+ def prepend(*records); end
918
+
919
+ sig do
920
+ abstract.params(
921
+ records: T.any(Elem, T::Enumerable[T.any(Elem, T::Enumerable[Elem])])
922
+ ).returns(T.self_type)
923
+ end
924
+ def push(*records); end
925
+
926
+ sig do
927
+ abstract.params(
928
+ other_array: T.any(Elem, T::Enumerable[T.any(Elem, T::Enumerable[Elem])])
929
+ ).returns(T::Array[Elem])
930
+ end
931
+ def replace(other_array); end
932
+
933
+ sig { abstract.returns(TypedAssociation::Relation[Elem]) }
934
+ def scope; end
935
+
936
+ sig { abstract.returns(T::Array[Elem]) }
937
+ def target; end
938
+ end
939
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-on-sorbet
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.8
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mateusz Drewniak
@@ -69,7 +69,9 @@ files:
69
69
  - lib/rails/on/sorbet/current_attributes.rb
70
70
  - lib/rails/on/sorbet/map.rb
71
71
  - lib/rails/on/sorbet/timelike.rb
72
+ - lib/rails/on/sorbet/typed_relation.rb
72
73
  - lib/rails/on/sorbet/version.rb
74
+ - lib/tapioca/dsl/compilers/rails_on_sorbet_active_record.rb
73
75
  - lib/tapioca/dsl/compilers/rails_on_sorbet_active_record_serializer.rb
74
76
  - lib/tapioca/dsl/compilers/rails_on_sorbet_alias_association.rb
75
77
  - lib/tapioca/dsl/compilers/rails_on_sorbet_currrent_attributes.rb
@@ -81,6 +83,7 @@ files:
81
83
  - rbi/map.rbi
82
84
  - rbi/numeric.rbi
83
85
  - rbi/set.rbi
86
+ - rbi/typed_relation.rbi
84
87
  homepage: https://github.com/espago/rails-on_sorbet
85
88
  licenses: []
86
89
  metadata: