title: ActiveRecord eager load multiple belongs_to associations
body: <h2>The problem</h2>
  
  <p>I have the following ActiveRecord model:</p>
  
  <pre><code>class Person
    belongs_to :favourite_car, class_name: 'Car'
    belongs_to :business_car, class_name: 'Car'
    belongs_to :home_car, class_name: 'Car'
  end
  </code></pre>
  
  <p>When I want to access all three of these associations, it generates three select queries:</p>
  
  <pre><code>SELECT * FROM cars WHERE cars.id = ?
  </code></pre>
  
  <p>This is essentially the <em>N+1 problem</em>.</p>
  
  <p>Ideally, I'd like it to generate just one query of the form</p>
  
  <pre><code>SELECT * FROM cars WHERE cars.id IN (?, ?, ?)
  </code></pre>
  
  <h2>Possible solution</h2>
  
  <p>I could move this to a <code>has_many :through =&gt; :join_table</code> association with a column in the join table to indicate what the association type is, then use <code>includes([:join_table, :cars])</code> to eager load the associations. However, in this case it only reduces 3 queries to 2, and introduces an extra table.</p>
  
  <h2>Another possible solution</h2>
  
  <p>Another possible solution would be to manually load the associations like so:</p>
  
  <pre><code>module EagerLoader
    def eager_load(*associations)
      reflections = associations.map { |association| self.class.reflections[association.to_sym] }
      raise 'Not all are valid associations' if reflections.any?(&amp;:nil?)
  
      reflections.group_by { |association| association.klass }.each do |klass, reflections|
        load_associations(klass, reflections)
      end
  
      self
  
    end
  
  private
  
    def load_associations(klass, reflections)
  
      primary_key = klass.primary_key
  
      ids = reflections.map { |reflection| public_send(reflection.foreign_key) }
  
      records = klass.where(id: ids)
  
  
      reflections.each_with_index do |reflection, i|
        record = records.find do |record|
          record.public_send(primary_key) == ids[i]
        end
  
        public_send("#{reflection.name}=", record)
      end
  
    end
  
  
  end
  </code></pre>
  
  <p>I have tested it, and it works.</p>
  
  <pre><code>class Person
    include EagerLoader
  end
  
  Person.find(2).eager_load(:favorite_car, :business_car, :home_car)
  </code></pre>
  
  <p>However, this still does not help you when you want to do things like</p>
  
  <pre><code>Person.includes(:favourite_car, :business_car, :home_car)
  </code></pre>
  
  <p>For example, on the person index page. This reduces the number of queries from 3N+1 to 4, but only 2 are actually needed.  </p>
  
  <p><strong>Are there any better solutions to this problem?</strong></p>