-
Notifications
You must be signed in to change notification settings - Fork 122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Infer types for active record fixtures #1871
Conversation
d0b52d7
to
181ece1
Compare
I was poking at creating this compiler as well and noticed it is possible to specify a model class in the fixture file itself. Could try |
Good point, will have a look at that, probably tomorrow though. |
Yep it does and matches the logic here for the in-file declaration to take precedent: https://github.com/rails/rails/blob/6d3fd5b98cc1c700fe9733521118abc7540546e7/activerecord/lib/active_record/fixtures.rb#L791-L793 |
67d53f1
to
c4956af
Compare
@bdewater @Morriar I managed to get it work (in the way I understand it to work). There are a couple of questions: Does this cover all needed cases? Does it seem reasonable to require I will try to run this against Core in a bit to see if this causes issues (thanks @Morriar for doing the first run!) and report back. The first run issues seemed unrelated but I have not dug a whole lot and now I want to make sure it actually matches expectations now and works. |
389170c
to
6185195
Compare
The tests are now failing on rails 7.0 due to missing Should that turn out to not be possible - thoughts on just supporting this for rails 7.1+ and going with |
I implemented a fallback to descendants of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One minor suggestion but it looks good to me 👍
d1e73aa
to
d732cb3
Compare
3dd652f
to
624c7ac
Compare
This is to discriminate between single argument calls which return a single model, e.g. User and multi argument calls which return an array of the model, e.g. T::Array[User]. This is the precursor to actually typing the return values since otherwise we would not be able to type it correctly.
This is to ensure that we handle namespaced models correctly in the return types of the fixtures.
fixture names to model names
This is for rails < 7.1 cases
624c7ac
to
5103ba8
Compare
Motivation
It has been bugging me some time that fixtures are T.untyped.
After a conversation today with @vinistock we realized that method overloading might work - and lo and behold - it does work.
The generated signatures return
Model
formodels(:one)
andT::Array[Model]
formodels(:one, :two)
by overloading it with nil as the rest arg type, hat tip to @vinistock for the idea.Implementation
The signature of the fixture methods changed from
users(*fixture_names)
tousers(fixture_name, *other_fixutres)
in order to allow overloading based on the type of the rest args (e.g.nil
orT.any(String, Symbol
).The mapping for fixture method (e.g.
users
) to model name (e.g.User
) happens by creating a lookup table (once) for a mapping from underscore name to name. All descendants ofActiveRecord::Base
go into the lookup table.This is required since there are potential conflicts with the fixture method name between
FooBar
andFoo::Bar
which both map tofoo_bars
.By building this lookup table once we can map this reasonably efficiently and correctly.
Should no matching model be found it falls back to T.untyped.
Do we have some way of collecting metrics if/how often this happens?
I added an ad-hoc implementation for turning the
Blog::Post
intoblog_posts
- I would assume there is something like that already but I did not find it - any pointers would be more than welcome!Tests
I modified the class documentation and tests to account for the changed signature and added the correct return types.
I also modified one test case to have a namespaces model
Post
->Blog::Post
to ensure that namespaced models are handled correctly and I also added a test that ensures the fallback toT.untyped
happens as expected.I also ran this on a personal project of mine (rails app with ~10k lines of ruby) and it worked as expected and
srb tc
still passed (meaning I used the fixtures as expected but also, at least for my case, it generated reasonable rbis)