Module: NoBrainer::Document::References

Extended by:
ActiveSupport::Concern
Included in:
NoBrainer::Document
Defined in:
lib/no_brainer/document/references.rb,
lib/no_brainer/references/eager_loader.rb

Defined Under Namespace

Modules: AssociationExt, ClassMethods

Class Method Summary collapse

Class Method Details

.eager_load(docs, field_name, field = nil, criteria = nil) ⇒ Object

adapted from NoBrainer::Document::Association::EagerLoader

Raises:

  • (TypeError)


7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/no_brainer/references/eager_loader.rb', line 7

def self.eager_load(docs, field_name, field=nil, criteria=nil)
  return  if docs.blank?

  field_name = field_name.to_sym
  field ||= docs.first.root_class.fields[field_name]
  ref_type = field_type = field[:type]
  if (field_type <= Array) && field_type.respond_to?(:object_type) && (field_type.object_type <= NoBrainer::Reference)
    ref_type = field_type.object_type
  end
  raise TypeError, "#{ref_type} is not a NoBrainer::Reference"  unless ref_type <= NoBrainer::Reference
  model_type = ref_type.model_type

  refs = docs.flat_map { |doc|  doc.read_attribute(field_name) }
  refs.compact!
  refs.reject!(&:__hasobj__)

  if refs.present?
    target_key = model_type.table_config.primary_key.to_sym
    ref_ids = refs.map(&:id).uniq

    query = model_type.without_ordering
    query = query.merge(criteria)  if criteria
    targets = query.where(target_key.in => ref_ids).group_by(&target_key)
    refs.each do |ref|
      if (target = targets[ref.id]&.first)
        ref.__setobj__(target)
      end
    end
    refs.uniq!
  end

  docs.select { |doc| Array(doc.read_attribute(field_name)).all?(&:__hasobj__) }
end