Module: AdvancedAR::ArbitraryPrefetch

Defined in:
lib/advanced_ar/arbitrary_prefetch.rb

Overview

Add support for creating arbitrary associations when using ActiveRecord Adds a prefetch method to ActiveRecord Queries.

This method accepts a Hash. The keys of the Hash represent how the Association will be made available.
The values of the Hash may be an array of [Symbol, Relation] or another (filtered) Relation.
Objects are queried from an existing Association on the model. This Association is detemrined
by either the Symbol when an array is passed, or by finding an Assoication for the passed Relation's model

NOTICE: This implementation is NOT COMPLETE by itself - it depends on Goldiloader

to detect the use of the virtual associations and prevent N+1s. We were already using
Goldiloader, so this made sense. If this module is ever needed stand-alone,
the following options have been identified:
  1. Extend ActiveRecordRelationPatch#exec_queries to execute an ActiveRecord::Associations::Preloader
     that will load the related objects
  2. Duplicates the relevant snippets from Goldiloader into this module. See Goldiloader::AutoIncludeContext
The current Goldiloader implementation uses Option 1 internally, but also makes the relations lazy - even
  if you define a prefetch, it won't actually be loaded until you attempt to access it on one of the models.

Defined Under Namespace

Modules: ActiveRecordBasePatch, ActiveRecordMergerPatch, ActiveRecordRelationPatch Classes: PrefetcherContext

Class Method Summary collapse

Class Method Details

.installObject



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/advanced_ar/arbitrary_prefetch.rb', line 145

def self.install
  ::ActiveRecord::Base.include(ActiveRecordBasePatch)
  ::ActiveRecord::Relation.prepend(ActiveRecordRelationPatch)
  ::ActiveRecord::Relation::Merger.prepend(ActiveRecordMergerPatch)

  return unless defined? ::Goldiloader

  ::Goldiloader::AssociationLoader.module_eval do
    def self.has_association?(model, association_name) # rubocop:disable Naming/PredicateName
      model.association(association_name)
      true
    rescue ::ActiveRecord::AssociationNotFoundError => _err
      false
    end
  end
end