Class: ActiveRecord::Associations::Preloader::Branch
- Inherits:
-
Object
- Object
- ActiveRecord::Associations::Preloader::Branch
- Defined in:
- lib/active_record/associations/preloader/branch.rb
Overview
:nodoc:
Instance Attribute Summary collapse
-
#associate_by_default ⇒ Object
readonly
Returns the value of attribute associate_by_default.
-
#association ⇒ Object
readonly
Returns the value of attribute association.
-
#children ⇒ Object
readonly
Returns the value of attribute children.
-
#parent ⇒ Object
readonly
Returns the value of attribute parent.
- #preloaded_records ⇒ Object
-
#scope ⇒ Object
readonly
Returns the value of attribute scope.
Instance Method Summary collapse
- #done? ⇒ Boolean
- #future_classes ⇒ Object
- #grouped_records ⇒ Object
- #immediate_future_classes ⇒ Object
-
#initialize(association:, children:, parent:, associate_by_default:, scope:) ⇒ Branch
constructor
A new instance of Branch.
- #likely_reflections ⇒ Object
- #loaders ⇒ Object
- #polymorphic? ⇒ Boolean
- #preloaders_for_reflection(reflection, reflection_records) ⇒ Object
- #root? ⇒ Boolean
- #runnable_loaders ⇒ Object
- #source_records ⇒ Object
- #target_classes ⇒ Object
Constructor Details
#initialize(association:, children:, parent:, associate_by_default:, scope:) ⇒ Branch
Returns a new instance of Branch.
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/active_record/associations/preloader/branch.rb', line 11 def initialize(association:, children:, parent:, associate_by_default:, scope:) @association = if association begin @association = association.to_sym rescue NoMethodError raise ArgumentError, "Association names must be Symbol or String, got: #{association.class.name}" end end @parent = parent @scope = scope @associate_by_default = associate_by_default @children = build_children(children) @loaders = nil end |
Instance Attribute Details
#associate_by_default ⇒ Object (readonly)
Returns the value of attribute associate_by_default.
8 9 10 |
# File 'lib/active_record/associations/preloader/branch.rb', line 8 def associate_by_default @associate_by_default end |
#association ⇒ Object (readonly)
Returns the value of attribute association.
7 8 9 |
# File 'lib/active_record/associations/preloader/branch.rb', line 7 def association @association end |
#children ⇒ Object (readonly)
Returns the value of attribute children.
7 8 9 |
# File 'lib/active_record/associations/preloader/branch.rb', line 7 def children @children end |
#parent ⇒ Object (readonly)
Returns the value of attribute parent.
7 8 9 |
# File 'lib/active_record/associations/preloader/branch.rb', line 7 def parent @parent end |
#preloaded_records ⇒ Object
68 69 70 |
# File 'lib/active_record/associations/preloader/branch.rb', line 68 def preloaded_records @preloaded_records ||= loaders.flat_map(&:preloaded_records) end |
#scope ⇒ Object (readonly)
Returns the value of attribute scope.
8 9 10 |
# File 'lib/active_record/associations/preloader/branch.rb', line 8 def scope @scope end |
Instance Method Details
#done? ⇒ Boolean
72 73 74 |
# File 'lib/active_record/associations/preloader/branch.rb', line 72 def done? root? || (@loaders && @loaders.all?(&:run?)) end |
#future_classes ⇒ Object
27 28 29 |
# File 'lib/active_record/associations/preloader/branch.rb', line 27 def future_classes (immediate_future_classes + children.flat_map(&:future_classes)).uniq end |
#grouped_records ⇒ Object
80 81 82 83 84 85 86 87 88 89 |
# File 'lib/active_record/associations/preloader/branch.rb', line 80 def grouped_records h = {} polymorphic_parent = !root? && parent.polymorphic? source_records.each do |record| reflection = record.class._reflect_on_association(association) next if polymorphic_parent && !reflection || !record.association(association).klass (h[reflection] ||= []) << record end h end |
#immediate_future_classes ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/active_record/associations/preloader/branch.rb', line 31 def immediate_future_classes if parent.done? loaders.flat_map(&:future_classes).uniq else likely_reflections.reject(&:polymorphic?).flat_map do |reflection| reflection. chain. map(&:klass) end.uniq end end |
#likely_reflections ⇒ Object
53 54 55 56 57 58 |
# File 'lib/active_record/associations/preloader/branch.rb', line 53 def likely_reflections parent_classes = parent.target_classes parent_classes.filter_map do |parent_klass| parent_klass._reflect_on_association(@association) end end |
#loaders ⇒ Object
118 119 120 121 122 123 |
# File 'lib/active_record/associations/preloader/branch.rb', line 118 def loaders @loaders ||= grouped_records.flat_map do |reflection, reflection_records| preloaders_for_reflection(reflection, reflection_records) end end |
#polymorphic? ⇒ Boolean
108 109 110 111 112 113 114 115 116 |
# File 'lib/active_record/associations/preloader/branch.rb', line 108 def polymorphic? return false if root? return @polymorphic if defined?(@polymorphic) @polymorphic = source_records.any? do |record| reflection = record.class._reflect_on_association(association) reflection && reflection.[:polymorphic] end end |
#preloaders_for_reflection(reflection, reflection_records) ⇒ Object
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/active_record/associations/preloader/branch.rb', line 91 def preloaders_for_reflection(reflection, reflection_records) reflection_records.group_by do |record| klass = record.association(association).klass if reflection.scope && reflection.scope.arity != 0 # For instance dependent scopes, the scope is potentially # different for each record. To allow this we'll group each # object separately into its own preloader reflection_scope = reflection.join_scopes(klass.arel_table, klass.predicate_builder, klass, record).inject(&:merge!) end [klass, reflection_scope] end.map do |(rhs_klass, reflection_scope), rs| preloader_for(reflection).new(rhs_klass, rs, reflection, scope, reflection_scope, associate_by_default) end end |
#root? ⇒ Boolean
60 61 62 |
# File 'lib/active_record/associations/preloader/branch.rb', line 60 def root? parent.nil? end |
#runnable_loaders ⇒ Object
76 77 78 |
# File 'lib/active_record/associations/preloader/branch.rb', line 76 def runnable_loaders loaders.flat_map(&:runnable_loaders).reject(&:run?) end |
#source_records ⇒ Object
64 65 66 |
# File 'lib/active_record/associations/preloader/branch.rb', line 64 def source_records @parent.preloaded_records end |
#target_classes ⇒ Object
43 44 45 46 47 48 49 50 51 |
# File 'lib/active_record/associations/preloader/branch.rb', line 43 def target_classes if done? preloaded_records.map(&:klass).uniq elsif parent.done? loaders.map(&:klass).uniq else likely_reflections.reject(&:polymorphic?).map(&:klass).uniq end end |