-
Notifications
You must be signed in to change notification settings - Fork 525
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
Relations: #decorate
queries DB every time
#944
base: master
Are you sure you want to change the base?
Relations: #decorate
queries DB every time
#944
Conversation
fbd0580
to
bb295d1
Compare
CI seems to be failing due to an issue with codeclimate. |
It looks like the test is failing:
|
I think that failing test would be fixed by #943. Without that, as each test creates posts, they remain in the DB, potentially influencing future tests. In the test that's failing, we're creating 0-2 posts, then asserting the decorated relation (all posts) matches the created posts, but the decorated relation is including some posts from prior tests, not just the posts created for this example. |
IMO, it would be perfect if tests do not depend on the DB state or other tests. |
I think it'd help to get clarity on #943 first. If that's rejected because it's by design that the DB is not reset between each example and data from one example should leak into the next example (and leak from one run to the next run locally), then I'll rework the test here to be less affected by existing data in the DB. I agree with the sentiment of one test not being dependent on another test, and #943 truly enforces that, as any data created for one test is wiped out before the next test. Without #943, I think it becomes slightly trickier (though doable) to write tests as it needs to pass with whatever data is lingering in my local test DB, whatever data is lingering in your local test DB, and whatever data might linger in the CI DB from previous tests. With #943, I find the test runs to be more repeatable and deterministic as each test is exactly in control of what's in the DB for that test. If it helps, rspec-rails by-default enables transactional fixtures (#943) in their generated rails helper: |
Similar to drapergem#932 for associations, calling `#decorate` on a relation loads the records every time, regardless of whether the underlying relation has already been loaded. This is because the default of passing `all` as the collection to decorate ends up being a new relation, so even if it were previously loaded, the new relation including `all` needs to be loaded. `ActiveRecord::Associations::CollectionProxy` actually inherits from `ActiveRecord::Relation`, so by pushing this up to the relation, we can cover both scenarios. https://github.com/rails/rails/blob/57c24948eb5cc9e5f9a4cecb6f2060f53e2246e1/activerecord/lib/active_record/associations/collection_proxy.rb#L31 The documentation included in drapergem#932 (`company.products.popular.decorate`) wasn't correct as you're decorating a relation there (`popular`), not just the association (`products`). This now covers the association itself (`company.products.decorate`), as well as a relation from that association (`company.products.popular.decorate`), as well as a relation right from the class without associations (`Product.popular.decorate`). Decorating the class itself (`Product.decorate`) still calls `all` since the model class is not a relation itself.
bb295d1
to
6c0ea6c
Compare
It still fails with Ruby 2.4. Unfortunately, those outdated actions are required and I can’t change that. Me and @y-yagi aren’t granted all the rights here. |
According to https://www.ruby-lang.org/en/downloads/branches/ Ruby 3.0 and lower are no longer receiving updates, so we can probably stop supporting them. |
Similar to #932 for associations, calling
#decorate
on a relation loads the records every time, regardless of whether the underlying relation has already been loaded.This is because the default of passing
all
as the collection to decorate ends up being a new relation, so even if it were previously loaded, the new relation includingall
needs to be loaded.ActiveRecord::Associations::CollectionProxy
actually inherits fromActiveRecord::Relation
, so by pushing this up to the relation, we can cover both scenarios.https://github.com/rails/rails/blob/57c24948eb5cc9e5f9a4cecb6f2060f53e2246e1/activerecord/lib/active_record/associations/collection_proxy.rb#L31
The documentation included in #932 (
company.products.popular.decorate
) wasn't correct as you're decorating a relation there (popular
), not just the association (products
).This now covers the association itself (
company.products.decorate
), as well as a relation from that association (company.products.popular.decorate
), as well as a relation right from the class without associations (Product.popular.decorate
).Decorating the class itself (
Product.decorate
) still callsall
since the model class is not a relation itself.I had to tweak one association test as previously
load_target
would eagerly load the association's records when decorating, whereas now the decorated association is still lazy so the records wont actually be loaded until you iterate over the decorated collection.