'CollectionProxy vs AssociationRelation

I am wondering about 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 is the difference between them and why this is implemented this way?



Solution 1:[1]

Ok. The difference is pretty simple.

Explanation based on your example:

the association proxy in v.wheels has:

  • the object in v as @owner;
  • the collection of its wheels as @target;
  • and the @reflection object represents a :has_many macro.

From docs:

Association proxies in Active Record are middlemen between the @owner and the @target. The @target object is not loaded until needed.

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

Which means, as soon as you call any method on the @target object (that holds collection of wheels in our case) the @target is loaded, and it becomes ActiveRecord_AssociationRelation.

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

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Andrey Deineko