lib/optimizations/associations/macro.rb in methodmissing-scrooge-2.2.3 vs lib/optimizations/associations/macro.rb in methodmissing-scrooge-3.0.0

- old
+ new

@@ -6,121 +6,84 @@ class << self # Inject into ActiveRecord # def install! - if scrooge_installable? + unless scrooge_installed? ActiveRecord::Base.send( :extend, SingletonMethods ) - ActiveRecord::Base.send( :include, InstanceMethods ) + ActiveRecord::Associations::AssociationProxy.send( :include, InstanceMethods ) end end - private + protected - def scrooge_installable? - !ActiveRecord::Base.included_modules.include?( InstanceMethods ) + def scrooge_installed? + ActiveRecord::Associations::AssociationProxy.included_modules.include?( InstanceMethods ) end end end module SingletonMethods @@preloadable_associations = {} - FindAssociatedRegex = /find_associated_records/ def self.extended( base ) eigen = class << base; self; end - eigen.instance_eval do - # Let :scrooge_callsite be a valid find option - # - remove_const(:VALID_FIND_OPTIONS) - const_set( :VALID_FIND_OPTIONS, [ :conditions, :include, :joins, :limit, :offset, :order, :select, :readonly, :group, :having, :from, :lock, :scrooge_callsite ] ) - end - eigen.alias_method_chain :find, :scrooge - eigen.alias_method_chain :find_every, :scrooge + # not used at present end - - # Let .find setup callsite information and preloading. - # - def find_with_scrooge(*args) - options = args.extract_options! - validate_find_options(options) - set_readonly_option!(options) - if (_caller = caller).grep( FindAssociatedRegex ).empty? - cs_signature = callsite_signature( _caller, options.except(:conditions, :limit, :offset) ) - options[:scrooge_callsite], options[:include] = cs_signature, scrooge_callsite(cs_signature).preload( options[:include] ) + def preload_scrooge_associations(result_set, callsite_sig) + scrooge_preloading_exclude do + callsite_associations = scrooge_callsite(callsite_sig).associations.to_a + preload_associations(result_set, callsite_associations) unless callsite_associations.empty? end - - case args.first - when :first then find_initial(options) - when :last then find_last(options) - when :all then find_every(options) - else find_from_ids(args, options) - end end - - # Override find_ever to pass along the callsite signature - # - def find_every_with_scrooge(options) - include_associations = merge_includes(scope(:find, :include), options[:include]) - if include_associations.any? && references_eager_loaded_tables?(options) - records = find_with_associations(options) - else - records = find_by_sql(construct_finder_sql(options), options[:scrooge_callsite]) - if include_associations.any? - preload_associations(records, include_associations) - end + def scrooge_preloading_exclude + unless Thread.current[:scrooge_preloading] + Thread.current[:scrooge_preloading] = true + yield + Thread.current[:scrooge_preloading] = false end - - records.each { |record| record.readonly! } if options[:readonly] - - records - end + end # Let's not preload polymorphic associations or collections # def preloadable_associations - @@preloadable_associations[self.name] ||= reflect_on_all_associations.reject{|a| a.options[:polymorphic] || a.macro == :has_many }.map{|a| a.name } - end - + @@preloadable_associations[self.name] ||= + reflect_on_all_associations.reject{|a| a.options[:polymorphic] || a.macro == :has_many}.map(&:name) + end + end module InstanceMethods - - # Association getter with Scrooge support - # - def association_instance_get(name) - association = instance_variable_get("@#{name}") - if association.respond_to?(:loaded?) - scrooge_seen_association!( name ) - association - end + + def self.included( base ) + base.alias_method_chain :load_target, :scrooge end - # Association setter with Scrooge support + # note AssociationCollection has its own version of load_target, but we don't + # do collections at the moment anyway # - def association_instance_set(name, association) - scrooge_seen_association!( name ) - instance_variable_set("@#{name}", association) + def load_target_with_scrooge + scrooge_seen_association!(@reflection.name) + load_target_without_scrooge end - - # Register an association with Scrooge - # - def scrooge_seen_association!( association ) - if scrooged? && !scrooge_seen_association?( association ) - @attributes.scrooge_associations << association - self.class.scrooge_callsite( @attributes.callsite_signature ).association!( association ) - end - end - + private - def scrooge_seen_association?( association ) - @attributes.scrooge_associations.include?( association ) + # Register an association with Scrooge + # + def scrooge_seen_association!( association ) + if @owner.scrooged? && !@loaded + @owner.class.scrooge_callsite(callsite_signature).association!(association) + end + end + + def callsite_signature + @owner.instance_variable_get(:@attributes).callsite_signature end end end \ No newline at end of file