title: Eager-Loading External Data Associated with an Active Record Model
body: <p>I am trying to combine data from an <code>ActiveRecord</code> model with external data related to each object and I'm trying to figure out a clean and performant way to accomplish this. </p>
  
  <p>I can obviously define an instance method on the model to fetch the corresponding external data:</p>
  
  <pre><code>class State &lt; ActiveRecord::Base
    def counties
      @counties ||= fetch_external_data(state: name)['counties']
    end
  end
  
  State.find_by_name('Alabama').counties
  </code></pre>
  
  <p>But if I have a collection of objects (via an <code>ActiveRecord::Relation</code>), then this would result in an N+1 query to this external data source.</p>
  
  <pre><code>State.where(name: %w[Alabama Georgia]).map(&amp;:counties)
  </code></pre>
  
  <p>Ideally, I would eager-load all of the data from the external data source and then have the <code>counties</code> instance method access data from this "shared" object. I could do this using a class method:</p>
  
  <pre><code>class State &lt; ActiveRecord::Base
  
    attr_accessor :counties
  
    def self.with_counties
      # Get external data for all states in our scope
      counties = fetch_external_data(states: pluck(:name))
  
      # Group by the state
      counties_by_state = counties.group_by { |c| c['state'] }
  
      # Now hydrate all of the state models and set the counties
      all.map do |state|
        state.counties = counties_by_state.dig(state.name, 'counties')
      end
    end
  end
  </code></pre>
  
  <p>While this is possible, it prevents me from being able to further chain scopes after using <code>State.where(name: %w[Alabama Georgia]).with_counties</code> and it just feels like it could be handled more elegantly.</p>
  
  <p>Is there a clear way to "eager-load" data like this (i.e. being able to set "collection data" on the <code>ActiveRecord::Relation</code> object that can be accessed when the record is hydrated)? If I have a class that represents this external data interface, are there methods that I could define on this class to make it work with <code>State.includes(:counties)</code> or <code>State.eager_load(:counties)</code>?</p>
  
  <p>Any thoughts or suggestions would  be appreciated. </p>