Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where does ActiveRecord::Associations::CollectionProxy get the .each instance method?

Let's say I have models Topics and Posts, where a Topic has_many :posts and a Post belongs_to :topic. I already have some stuff in my database at this point.

If I go into the rails console and type

Topic.find(1).posts

I believe I get back a CollectionProxy object.

=> #<ActiveRecord::Associations::CollectionProxy [#<Post id:30, ......>]>

I can call .each on this to get an Enumerator object.

=> #<Enumerator: [#<Post id: 30, ......>]:each>

I'm confused as to how CollectionProxy is handling .each. I realize that it's inherited at some point but I've been reading the API docs and they don't make it very clear what CollectionProxy is inheriting from unless I'm missing something obvious.

This page doesn't seem to tell me much, and neither does this page.

like image 956
lynk Avatar asked Jul 11 '15 02:07

lynk


People also ask

What is ActiveRecord:: Associations:: CollectionProxy?

Class: ActiveRecord::Associations::CollectionProxyAssociation proxies in Active Record are middlemen between the object that holds the association, known as the @owner , and the actual associated object, known as the @target . The kind of association any proxy is about is available in @reflection .

What is an ActiveRecord relation?

An instance of ActiveRecord::Base is an object that represents a specific row of your database (or might be saved into the database). Whereas an instance of ActiveRecord::Relation is a representation of a query that can be run against your database (but wasn't run yet).

What is pluck in Ruby?

ruby rails. Rails has a great, expressive term called pluck that allows you to grab a subset of data from a record. You can use this on ActiveRecord models to return one (or a few) columns. But you can also use the same method on regular old Enumerables to pull out all values that respond to a given key.


2 Answers

ActiveRecord::Associations::CollectionProxy is inherited from Relation, and Relation forwards each and many other methods to to_a.

From activerecord/lib/active_record/relation/delegation.rb#L45

delegate :to_xml, :to_yaml, :length, :collect, :map, :each, :all?, :include?, :to_ary, :join, to: :to_a

See Understanding Ruby and Rails: Delegate for an excellent explanation on how delegate works.

like image 66
Prakash Murthy Avatar answered Nov 18 '22 13:11

Prakash Murthy


Why don't you try asking it where it comes from?

> ActiveRecord::Associations::CollectionProxy.instance_method(:each).owner
=> ActiveRecord::Delegation 

The UnboundMethod#owner method:

Returns the class or module that defines the method.

so each comes from ActiveRecord::Delegation. And if you look at ActiveRecord::Delegation, you'll see this:

delegate ..., :each, ... , to: :to_a

so each is further punted to to_a.each.

like image 5
mu is too short Avatar answered Nov 18 '22 13:11

mu is too short