-
Notifications
You must be signed in to change notification settings - Fork 21.8k
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
Preload no longer associates record with owner when custom scope is passed #36638
Comments
@NoNonsenseSolutions that will be impossible now. This functionality is not officially documented, so I am pretty sure we can not consider this a bug. What is your use case on having a custom scope for association in particular context? |
While I agree that it's undocumented, there's precedent of other users using it. For example, in this blog post. http://aserafin.pl/2017/09/12/preloading-associations-with-dynamic-condition-in-rails/ Another common use case would be to check whether a user has 'liked' a collection of resources. The current change will cause all applications that were previously using this functionality to break silently. If a custom scope will never be useful, perhaps the change should remove that option from the method and throw an explicit error. |
I didn't quite get the use case. Can you show me the code that uses
The option is used internally, that is why it is there, not because someone uses it explicitly. Rails will always have breaking changes for undocumented things because they are not part of the test suite and there is no other way to ensure a consistent behavior without it. If you want to relay on that, consider convincing the core team to add the related test case, otherwise write that test on the application side to ensure it never breaks silently. There are many other ways to fix that:
But I just want to confirm that your use case makes sense and that the core team considers this an issue to be addressed. |
The blog post i linked has an example
This would allow you to preload only the necessary prices Another example would be
|
Ok, so if core team would confirm that activerecord needs this feature, I can add a special option like |
have some serious issue here too because of that (especially using / trying to port graphql-preload for rails 6), a gem which is pretty useful and still used by some people |
We also stumbled upon this issue. Before finding this issue already open I prepared the following gist to reproduce. |
To add another vote and use case for passing a custom scope on the preloader, I ended up here trying to chase down why I can't get the trick to work from the blog post @NoNonsenseSolutions already mentioned. My use case is to preload, on a collection of |
This also breaks functionality of gems like For example I'm using custom scopes to ensure custom ordering of associated records. class GraphQL::Types::User < GraphQL::Types::BaseObject
field :accounts, [Graphql::Types::Account], null: false do
preload :accounts
preload_scope ::Account.where(deleted: false).order(id: :asc)
description "Linked accounts"
end
end Which will execute something like that if and only if a client will ask for user's accounts in GraphQL query: ActiveRecord::Associations::Preloader.new.preload([u1, u2], :accounts, Account.where(deleted: false).order(id: :asc)) |
Here is a possible workaround: ::ActiveRecord::Associations::Preloader.new.preload(records, :association, :scope).then(&:first).then do |preloader|
preloader.send(:owners).each do |owner|
preloader.send(:associate_records_to_owner, owner, preloader.records_by_owner[owner] || [])
end
end Or for those struggling with
Yeah, Preloader is not a part of the public API. So, I wouldn't expect Core Team consider it a bug as well. |
@palkan exactly 🙌 |
Well, I can’t agree here. It seems that the association preloader became way too widely adopted to ignore its importance for various gems and projects. It is hard to think about it as “private” when it was actually “documented” in various blog posts throughout the last years and is being used in many gems (including quite popular ones). |
This makes it even harder to have dynamic scopes. The preloader was a good workaround for the problems described here: #3912. Now without the preloader route, I again have to spend hours trying to fix these kind of queries. Other ORM frameworks make this kind of stuff soo much easier that ActiveRecords nowadays really starts feeling like a pain to work with. |
I'm unsure if I did understand the problem correctly, but why are we using internal Rails mechanisms again? At least for @coorasse's gist, there's a straight-forward workaround using the public API: https://gist.github.com/coorasse/63fc88b58e13a2eae27e27d95e82db05#gistcomment-3216808 |
@schmijos I believe your solution joins the two tables, and filters accordingly. The preload functions differently, where you first load from the first table, and then preloads by running a query on the second table to load the associated data. |
I also have used preload to avoid some large memory issues being able to add additional associations in batches after filtering to the final list of needed original objects and associations. |
I think one of these is a duplicate #37720 |
Someone had relied on the behavior that preloading with a given scope, but the behavior has lost in rails#35496 to fix the minor bug that unloading through association. Basically we don't guarantee the internal behavior, but the bugfix can be achieved without any breaking change, so I've restored the lost functionality. Fixes rails#36638. Fixes rails#37720.
Someone had relied on the behavior that preloading with a given scope, but the behavior has lost in rails#35496 to fix the minor bug that unloading through association. Basically we don't guarantee the internal behavior, but the bugfix can be achieved without any breaking change, so I've restored the lost functionality. Fixes rails#36638. Fixes rails#37720. Signed-off-by: Grzegorz Derebecki <[email protected]>
Someone had relied on the behavior that preloading with a given scope, but the behavior has lost in rails#35496 to fix the minor bug that unloading through association. Basically we don't guarantee the internal behavior, but the bugfix can be achieved without any breaking change, so I've restored the lost functionality. Fixes rails#36638. Fixes rails#37720. Signed-off-by: Grzegorz Derebecki <[email protected]>
Steps to reproduce
ActiveRecord::Associations::Preloader.new.preload(records, :association, Association.scope)
Expected behavior
Preloaded records when using custom scope should be associated with owner
Actual behavior
Custom scope is loaded into hash #record_by_owner and not associated with owner.
This defeats the purpose of preloading the association with a custom scope.
System configuration
Rails version:
6.0.0rc1
Ruby version:
2.5.1
The text was updated successfully, but these errors were encountered: