Skip to content

Instantly share code, notes, and snippets.

@bakineggs
Created November 11, 2012 01:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bakineggs/4053241 to your computer and use it in GitHub Desktop.
Save bakineggs/4053241 to your computer and use it in GitHub Desktop.
Eager load an association that uses interpolation for a key constraint
class TabsController < ApplicationController
def index
@tabs = Tab.all :include => :available_balance
end
end
class Balance < ActiveRecord::Base
belongs_to :customer, :class_name => 'User'
belongs_to :merchant, :class_name => 'User'
end
class Tab < ActiveRecord::Base
belongs_to :customer, :class_name => 'User'
belongs_to :merchant, :class_name => 'User'
has_one :available_balance, :class_name => 'Balance', :primary_key => :customer_id, :foreign_key => :customer_id, :conditions => 'merchant_id in (#{available_balance_merchant_ids})'
def self.available_balance_merchant_ids; @records_to_preload.map(&:merchant_id).join ',' end # called when eager loading available_balance
def available_balance_merchant_ids; merchant_id end # called when lazy loading available_balance
end
# This patch enables access to the records being preloaded when eager loading
# an association whose conditions use interpolation to call class methods.
module ActiveRecord::AssociationPreload::ClassMethods
[:has_and_belongs_to_many, :has_one, :has_many, :belongs_to].each do |type|
define_method "preload_#{type}_association_with_access_to_records" do |records, reflection, *args|
@records_to_preload_for_reflection ||= {}
@records_to_preload_for_reflection[reflection] = records
send "preload_#{type}_association_without_access_to_records", records, reflection, *args
@records_to_preload_for_reflection.delete reflection
end
alias_method_chain "preload_#{type}_association", :access_to_records
end
def append_conditions_with_access_to_records reflection, *args
@records_to_preload = @records_to_preload_for_reflection[reflection]
sql = append_conditions_without_access_to_records reflection, *args
remove_instance_variable :@records_to_preload
sql
end
alias_method_chain :append_conditions, :access_to_records
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment