module NoBrainer::Document::Association::EagerLoader::Generic
Public Instance Methods
eager_load(docs, additional_criteria = nil)
click to toggle source
Used in associations to declare generic eager loading capabilities The association should implement loaded?, preload, eager_load_owner_key and eager_load_target_key.
# File lib/no_brainer/document/association/eager_loader.rb, line 10 def eager_load(docs, additional_criteria = nil) owner_key = eager_load_owner_key owner_type = eager_load_owner_type target_key = eager_load_target_key if is_a?(NoBrainer::Document::Association::BelongsTo::Metadata) && owner_type target_class = docs.first.__send__(owner_type) if docs.detect { |doc| doc.__send__(owner_type) != target_class } raise NoBrainer::Error::PolymorphicAssociationWithDifferentTypes, "The documents to be eager loaded doesn't have the same " \ 'type, which is not supported' end end criteria = target_class ? base_criteria(target_class) : base_criteria criteria = criteria.merge(additional_criteria) if additional_criteria unloaded_docs = docs.reject { |doc| doc.associations[self].loaded? } owner_keys = unloaded_docs.map(&owner_key).compact.uniq if owner_keys.present? targets = criteria.where(target_key.in => owner_keys) .map { |target| [target.read_attribute(target_key), target] } .each_with_object(Hash.new { |k,v| k[v] = [] }) { |(k,v),h| h[k] << v } unloaded_docs.each do |doc| doc_targets = targets[doc.read_attribute(owner_key)] doc.associations[self].preload(doc_targets) end end docs.map { |doc| doc.associations[self].read }.flatten.compact.uniq end