Module: ActiveRecord
- Defined in:
- lib/arel-helpers/ext/collection_proxy.rb
Overview
ActiveRecord as of version 4.0 defines a CollectionProxy class that lazily fetches records from the database. If posts has many comments, then post.comments returns a CollectionProxy that can be iterated over. A query to fetch the pertinent records isn’t fired until the iteration starts, so post.comments itself isn’t enough to cause a trip to the database.
ArelHelpers adds a [] method to ActiveRecord::Relation which means it also adds the same method to CollectionProxy, since CollectionProxy inherits from Relation. For some reason, CollectionProxy doesn’t define its own [] method but instead lets ActiveRecord’s complicated Delegation module handle calls to it via method_missing. In the post.comments case illustrated above, a call to [] is handled by this method_missing: github.com/rails/rails/blob/4-1-stable/activerecord/lib/active_record/relation/delegation.rb#L91 Here, @klass refers to the Comment model, which means [] calls on an instance of CollectionProxy actually get re-routed. Instead of calling
-
on a CollectionProxy like we were expecting, it calls [] on Comment,
and therefore on the mixed-in ArelHelpers::ArelTable. The final result is that the caller gets back an Arel::Attribute instead of the instance of Comment they were expecting.
This “simple” monkey patch defines [] on CollectionProxy so the convoluted method_missing logic in Delegation doesn’t get triggered, and therefore doesn’t end up returning an unexpected Arel::Attribute.
Defined Under Namespace
Modules: Associations