More accurately type ActiveRecordRelations calculation methods #1408
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Motivation
Currently the calculation methods like
sum
andcount
returnT.untyped
. For some methods we cannot know the type (e.g.minimum
) but for others we at least know it's numeric (e.g.sum
) and forcount
we know it's an Integer.However, I'm assuming these are untyped because if they're used with
group
the return value is actually a hash where the keys cannot be typed but the values will be the types mentioned above. This PR updates theActiveRecordRelations
compiler to type these correctly.Implementation
I first updated the return values of the calculation methods where possible. Then I largely copied from the code around
PrivateRelationWhereChain
to add aPrivateRelationGroupChain
module which defines the calculation methods with the hash return values.Some callouts:
GroupChain
runtime class available so this is solely made for RBI. From looking at the source it looks like when a query usesgroup
some metadata is added to it.group
anywhere in the query chain produces this behavior but to avoid needing to re-type every query method inside this module we make a simplifying assumption that the calculation method is called immediately after the group (e.g.group().count
and notgroup().where().count
). The one exception isgroup().having().count
which is fairly idiomatic so that gets handled without breaking the chain.Tests
Updated the existing specs.