class ActiveRecord::Associations::Preloader
Public Instance Methods
rubocop:enable Style/BlockDelimiters, Lint/AmbiguousBlockAssociation, Style/MethodCallWithArgsParentheses
# File lib/active_record/virtual_attributes/virtual_fields.rb, line 208 def display_virtual_attribute_deprecation(str) short_caller = caller # if debugging is turned on, don't prune the backtrace. # if debugging is off, prune down to the line where the sql is executed # this defaults to false and only displays 1 line number. unless ActiveSupport::Deprecation.debug bc = ActiveSupport::BacktraceCleaner.new bc.add_silencer { |line| line =~ /virtual_fields/ } bc.add_silencer { |line| line =~ /active_record/ } short_caller = bc.clean(caller) end ActiveSupport::Deprecation.warn(str, short_caller) end
preloader.rb active record 6.0 changed: different from 5.2. But not called outside these redefined methods here, so it works fine did add compact to fix a 5.2 double preload nil bug
# File lib/active_record/virtual_attributes/virtual_fields.rb, line 183 def grouped_records(orig_association, records, polymorphic_parent) h = {} records.compact.each do |record| # each class can resolve virtual_{attributes,includes} differently association = record.class.replace_virtual_fields(orig_association) # 1 line optimization for single element array: association = association.first if association.kind_of?(Array) && association.size == 1 case association when Symbol, String # 4/24/20 we want to revert #67 once we handle all these error cases in our codebase. reflection = record.class._reflect_on_association(association) display_virtual_attribute_deprecation("#{record.class.name}.#{association} does not exist") if !reflection && !polymorphic_parent next if !reflection || !record.association(association).klass when nil next else # need parent (preloaders_for_{hash,one}) to handle this Array/Hash reflection = association end (h[reflection] ||= []) << record end h end
rubocop:disable Style/BlockDelimiters, Lint/AmbiguousBlockAssociation, Style/MethodCallWithArgsParentheses preloader.rb active record 6.0 changed: passing polymorphic around (and makes 5.2 more similar to 6.0)
# File lib/active_record/virtual_attributes/virtual_fields.rb, line 155 def preloaders_for_hash(association, records, scope, polymorphic_parent) association.flat_map { |parent, child| grouped_records(parent, records, polymorphic_parent).flat_map do |reflection, reflection_records| loaders = preloaders_for_reflection(reflection, reflection_records, scope, polymorphic_parent) recs = loaders.flat_map(&:preloaded_records).uniq child_polymorphic_parent = reflection && reflection.respond_to?(:options) && reflection.options[:polymorphic] loaders.concat Array.wrap(child).flat_map { |assoc| preloaders_on assoc, recs, scope, child_polymorphic_parent } loaders end } end
preloader.rb active record 6.0 changed: passing polymorphic_parent to preloaders_for_reflection
# File lib/active_record/virtual_attributes/virtual_fields.rb, line 172 def preloaders_for_one(association, records, scope, polymorphic_parent) grouped_records(association, records, polymorphic_parent) .flat_map do |reflection, reflection_records| preloaders_for_reflection(reflection, reflection_records, scope, polymorphic_parent) end end
preloader.rb active record 6.0 changed: since grouped_records
can return a hash/array, we need to handle those 2 new cases
# File lib/active_record/virtual_attributes/virtual_fields.rb, line 108 def preloaders_for_reflection(reflection, records, scope, polymorphic_parent) case reflection when Array reflection.flat_map { |ref| preloaders_on(ref, records, scope, polymorphic_parent) } when Hash preloaders_on(reflection, records, scope, polymorphic_parent) else super(reflection, records, scope) end end
preloader.rb active record 6.0 since this deals with polymorphic_parent, it makes everything easier to just define it
# File lib/active_record/virtual_attributes/virtual_fields.rb, line 138 def preloaders_on(association, records, scope, polymorphic_parent = false) case association when Hash preloaders_for_hash(association, records, scope, polymorphic_parent) when Symbol, String preloaders_for_one(association.to_sym, records, scope, polymorphic_parent) else raise ArgumentError, "#{association.inspect} was not recognized for preload" end end