Another interesting use would be on octopus which would allow us to send the association query to the right shard: https://github.com/tchandy/octopus
We currently have a lot of monkey patches to make it work too: https://github.com/tchandy/octopus/blob/master/lib/octopus/association_shard_tracking.rb On Wednesday, June 25, 2014 9:28:36 PM UTC-3, Gabriel Sobrinho wrote: > > Hello guys, > > The Salsify Engineering team made a gem to automatic eager load > associations on rails, take a look here: > http://blog.salsify.com/engineering/automatic-eager-loading-rails > > If you want to avoid to read the entire post, they made this: > > > blogs = Blogs.limit(5).to_a > # SELECT * FROM blogs LIMIT 5 > > > blogs.each { |blog| blog.posts.to_a } > # SELECT * FROM posts WHERE blog_id IN (1,2,3,4,5) > > > Which I think that may make a huge sense for a lot of applications. > > > But active record seems to not provide a hook to do overwrite internals > like that, they had to monkey patch a lot of methods here: > https://github.com/salsify/goldiloader/blob/master/lib/goldiloader/active_record_patches.rb > > I’m not pretty comfortable with active record source code but my > suggestion is to make a accessor or a hook to use a custom collection proxy > class. > > > Currently when we call blog.posts we receive a > ActiveRecord::Associations::CollectionProxy object. > > What if we can change active record to use a custom builder object, or a > lambda, like that? > > ActiveRecord::Base.association_builder = lambda do |source, instance, > association| > SharedAssociationProxy.build(source: source, instance: instance, > association: association) > end > > class SharedAssociationProxy < ActiveRecord::Associations::CollectionProxy > def self.build(source:, instance:, association:) > registry[source, association] ||= new(source.klass, association) > registry[source, association].append(instance) > end > > def to_a(instance) > objects.select do |object| > object[reflection.primary_key] == object.id > end > end > > protected > > def objects > @objects ||= reflection.klass.where(reflection.primary_key => > instances.map(&:id)) > end > end > > blogs = Blogs.limit(5).to_a > blogs.first.posts # will use the blogs as source since it fetched a > collection > => SharedAssociationProxy.build(source: blogs, instance: blog, > association: :posts) > > blog = Blog.first > blog.posts # will use the blog as source since it was the only fetched > => SharedAssociationProxy.build(source: blog, instance: blog, association: > :posts) > > > Like I said, I’m not pretty comfortable with active record source code, > then I don’t know the exactly details that need to be passed to the > builder, lets focus just on the concept. > > If we want a toggle option like the fully_load made by Salsify guys, we > can just check for it on the lambda or the builder. > > About the to_a method, it would be necessary to receive the model instance > that is calling the to_a method to do the necessary work, it would happen > for all methods that can have a custom implementation: first, last, to_a, > etc. > > > What do you guys think about that? > > Cheers, > > Gabriel Sobrinho > gabrielsobrinho.com > > -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/rubyonrails-core. For more options, visit https://groups.google.com/d/optout.
