Module: JitPreloadExtension

Defined in:
lib/jit_preloader/active_record/base.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#jit_n_plus_one_trackingObject

Returns the value of attribute jit_n_plus_one_tracking.



3
4
5
# File 'lib/jit_preloader/active_record/base.rb', line 3

def jit_n_plus_one_tracking
  @jit_n_plus_one_tracking
end

#jit_preload_aggregatesObject

Returns the value of attribute jit_preload_aggregates.



4
5
6
# File 'lib/jit_preloader/active_record/base.rb', line 4

def jit_preload_aggregates
  @jit_preload_aggregates
end

#jit_preloaderObject

Returns the value of attribute jit_preloader.



2
3
4
# File 'lib/jit_preloader/active_record/base.rb', line 2

def jit_preloader
  @jit_preloader
end

Class Method Details

.prepended(base) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/jit_preloader/active_record/base.rb', line 19

def self.prepended(base)
  class << base
    delegate :jit_preload, to: :all

    def has_many_aggregate(assoc, name, aggregate, field, default: 0)
      method_name = "#{assoc}_#{name}"

      define_method(method_name) do |conditions={}|
        self.jit_preload_aggregates ||= {}

        key = "#{method_name}|#{conditions.sort.hash}"
        return jit_preload_aggregates[key] if jit_preload_aggregates.key?(key)
        if jit_preloader
          reflection = association(assoc).reflection
          primary_ids = jit_preloader.records.collect{|r| r[reflection.active_record_primary_key] }
          klass = reflection.klass

          aggregate_association = reflection
          while aggregate_association.through_reflection
            aggregate_association = aggregate_association.through_reflection
          end

          association_scope = klass.all.merge(association(assoc).scope).unscope(where: aggregate_association.foreign_key)
          association_scope = association_scope.instance_exec(&reflection.scope).reorder(nil) if reflection.scope

          conditions[aggregate_association.table_name] = { aggregate_association.foreign_key => primary_ids }
          if reflection.type.present?
            conditions[reflection.type] = self.class.name
          end
          group_by = "#{aggregate_association.table_name}.#{aggregate_association.foreign_key}"

          preloaded_data = Hash[association_scope
            .where(conditions)
            .group(group_by)
            .send(aggregate, field)
          ]

          jit_preloader.records.each do |record|
            record.jit_preload_aggregates ||= {}
            record.jit_preload_aggregates[key] = preloaded_data[record.id] || default
          end
        else
          self.jit_preload_aggregates[key] = send(assoc).where(conditions).send(aggregate, field) || default
        end
        jit_preload_aggregates[key]
      end
    end
  end
end

Instance Method Details

#clear_jit_preloader!Object



11
12
13
14
15
16
17
# File 'lib/jit_preloader/active_record/base.rb', line 11

def clear_jit_preloader!
  self.jit_preload_aggregates = {}
  if jit_preloader
    jit_preloader.records.delete(self)
    self.jit_preloader = nil
  end
end

#reload(*args) ⇒ Object



6
7
8
9
# File 'lib/jit_preloader/active_record/base.rb', line 6

def reload(*args)
  clear_jit_preloader!
  super
end