Module: Mongoid::Criteria::Includable
| Relationships & Source Files | |
| Extension / Inclusion / Inheritance Descendants | |
|
Included In:
| |
| Defined in: | lib/mongoid/criteria/includable.rb |
Overview
Module providing functionality for parsing (nested) inclusion definitions.
Instance Attribute Summary
-
#inclusions ⇒ Array<Mongoid::Association::Relatable>
rw
Get a list of criteria that are to be executed for eager loading.
-
#inclusions=(value) ⇒ Array<Mongoid::Association::Relatable>
rw
::Setthe inclusions for the criteria. -
#use_lookup? ⇒ true | false
readonly
Returns whether to use $lookup aggregation for eager loading.
Instance Method Summary
-
#eager_load(*relations) ⇒ Criteria
Eager loads all the provided associations using aggregation $lookup.
-
#includes(*relations) ⇒ Criteria
Eager loads all the provided associations.
-
#add_inclusion(association, parent = nil)
private
Add an inclusion definition to the list of inclusions for the criteria.
-
#extract_includes_list(_parent_class, parent, is_eager_load = false, *relations_list)
private
Iterate through the list of relations and create the inclusions list.
-
#resolve_inclusion_associations(parent_class, relation, is_eager_load) ⇒ Array<Mongoid::Association::Relatable>
private
Resolve the association(s) matching the given relation name.
Instance Attribute Details
#inclusions ⇒ Array<Mongoid::Association::Relatable> (rw)
Get a list of criteria that are to be executed for eager loading.
# File 'lib/mongoid/criteria/includable.rb', line 59
def inclusions @inclusions ||= [] end
#inclusions=(value) ⇒ Array<Mongoid::Association::Relatable> (rw)
::Set the inclusions for the criteria.
# File 'lib/mongoid/criteria/includable.rb', line 68
def inclusions=(value) @inclusions = value end
#use_lookup? ⇒ true | false (readonly)
Returns whether to use $lookup aggregation for eager loading. Only when eager_load was requested and there is something to load: an empty inclusion list (e.g. eager_load([])) falls back to the normal path.
# File 'lib/mongoid/criteria/includable.rb', line 52
def use_lookup? !!@use_lookup && inclusions.any? end
Instance Method Details
#add_inclusion(association, parent = nil) (private)
Add an inclusion definition to the list of inclusions for the criteria.
# File 'lib/mongoid/criteria/includable.rb', line 79
def add_inclusion(association, parent = nil) if assoc = inclusions.detect { |a| a == association } assoc.parent_inclusions.push(parent) if parent else assoc = association.dup assoc.parent_inclusions = [] assoc.parent_inclusions.push(parent) if parent inclusions.push(assoc) end end
#eager_load(*relations) ⇒ Criteria
Eager loads all the provided associations using aggregation $lookup. The behavior should be identical to #includes.
# File 'lib/mongoid/criteria/includable.rb', line 41
def eager_load(*relations) extract_includes_list(klass, nil, true, *relations) @use_lookup = ! clone end
#extract_includes_list(_parent_class, parent, is_eager_load = false, *relations_list) (private)
Iterate through the list of relations and create the inclusions list.
# File 'lib/mongoid/criteria/includable.rb', line 99
def extract_includes_list(_parent_class, parent, is_eager_load = false, *relations_list) relations_list.flatten.each do |relation_object| # Normalize a bare association name to a hash with no nested # inclusions, so both forms share one resolution path below. relations = relation_object.is_a?(Hash) ? relation_object : { relation_object => nil } relations.each do |relation, nested| associations = resolve_inclusion_associations(_parent_class, relation, is_eager_load) raise_eager_error(is_eager_load, _parent_class, relation) if associations.empty? associations.each do |association| add_inclusion(association, parent) extract_includes_list(association.klass, association.name, is_eager_load, nested) if nested end end end end
#includes(*relations) ⇒ Criteria
This will work for embedded associations that reference another collection via belongs_to as well.
Eager loading brings all the documents into memory, so there is a sweet spot on the performance gains. Internal benchmarks show that eager loading becomes slower around 100k documents, but this will naturally depend on the specific application.
Eager loads all the provided associations. Will load all the documents into the identity map whose ids match based on the extra query for the ids.
# File 'lib/mongoid/criteria/includable.rb', line 26
def includes(*relations) extract_includes_list(klass, nil, false, *relations) clone end
#resolve_inclusion_associations(parent_class, relation, is_eager_load) ⇒ Array<Mongoid::Association::Relatable> (private)
Resolve the association(s) matching the given relation name. For the regular #includes path, only the parent class is consulted. For the #eager_load ($lookup) path, its subclasses are consulted as well, so associations defined only on a subclass can also be eager-loaded when querying through the superclass.
# File 'lib/mongoid/criteria/includable.rb', line 128
def resolve_inclusion_associations(parent_class, relation, is_eager_load) if association = parent_class.reflect_on_association(relation) return [ association ] end return [] unless is_eager_load parent_class.descendants.filter_map { |sub| sub.reflect_on_association(relation) } end