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.

Reply via email to