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.
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 .
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).
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.
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.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With