CollectionProxy vs AssociationRelation

I am interested to know the difference between ActiveRecord::Associations::CollectionProxy and ActiveRecord::AssociationRelation .

 class Vehicle < ActiveRecord::Base has_many :wheels end class Wheel < ActiveRecord::Base belongs_to :vehicle end 

So if I do:

v = Vehicle.new

v.wheels # => #<ActiveRecord::Associations::CollectionProxy []>

v.wheels.all # => #<ActiveRecord::AssociationRelation []>

I have no idea what the difference is between them and why it is implemented in this way?

+5
source share
2 answers

ActiveRecord::Relation are simple query objects before turning them into a query and executing, CollectionProxy , on the other hand, is a bit more complicated.

First of all, you get an extension of the association, you probably saw something similar to this, suppose a bookstore model in which there are a lot of books.

 class Store < ActiveRecord::Base has_many :books do def used where(is_used: true) end end end 

In this way, you can call up used books in the store using the syntax that looks like this

 Store.first.books.used 

But this is the most basic use, you can use the attributes that are available to you in the collection proxy, which are owner , reflection and target

Owner

owner provides a reference to the parent containing the association

Reflection

The reflection object is an instance of ActiveRecord::Reflection::AssocciationReflection and contains all the configuration parameters for the association.

goal

target are association collection objects (or a single object when has_one and belongs_to ).

Using these methods, you can make some conditions in expanding your association, for example, if we have a blog, we provide access to all deleted messages for users who are administrators (an example of a lame one that I know)

 Class Publisher < ActiveRecord::Base has_many :posts do def deleted if owner.admin? Post.where(deleted: true) else where(deleted: true) end end end end 

You also get access to two other methods that reset and reload , the first ( reset ) clears the objects of the cached association, the second ( reload ) is more common and is used to reset , and then loads the related objects from the database.

Hope this explains how the CollectionProxy class would be so useful.

+12
source

Ok The difference is pretty simple.

Explanation based on your example:

association proxy server in v.wheels has:

  • object in v as @owner;
  • wheel collection like @target;
  • and the @reflection object represents the macro :has_many .

From docs :

The association providers in Active Record are intermediaries between the owner of @owner and @target. The @target object does not load until required.

 v = Vehicle.new v.wheels # we are not sending any methods to @target object (collection of wheels) # => #<ActiveRecord::Associations::CollectionProxy []> 

This means that as soon as you call some method in the @target object (which stores the wheels collection in our case), @target is loaded and becomes ActiveRecord_AssociationRelation .

 v.wheels.all # sending the `all` method to @target (wheels) # => #<ActiveRecord::AssociationRelation []> 
+7
source

Source: https://habr.com/ru/post/1235839/


All Articles