Class: Bullet::Detector::UnusedEagerLoading

Inherits:
Association show all
Extended by:
Bullet::Dependency, StackTraceFilter
Defined in:
lib/bullet/detector/unused_eager_loading.rb

Constant Summary

Constants included from StackTraceFilter

StackTraceFilter::IS_RUBY_19, StackTraceFilter::VENDOR_PATH

Class Method Summary collapse

Methods included from Bullet::Dependency

active_record40?, active_record41?, active_record42?, active_record4?, active_record50?, active_record51?, active_record52?, active_record5?, active_record60?, active_record61?, active_record6?, active_record70?, active_record71?, active_record72?, active_record7?, active_record80?, active_record8?, active_record?, active_record_version, mongoid4x?, mongoid5x?, mongoid6x?, mongoid7x?, mongoid8x?, mongoid?, mongoid_version

Methods included from StackTraceFilter

caller_in_project, excluded_stacktrace_path?

Methods inherited from Association

add_call_object_associations, add_object_associations, impossible_objects, possible_objects

Class Method Details

.add_eager_loadings(objects, associations) ⇒ Object



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
# File 'lib/bullet/detector/unused_eager_loading.rb', line 30

def add_eager_loadings(objects, associations)
  return unless Bullet.start?
  return unless Bullet.unused_eager_loading_enable?
  return if objects.map(&:bullet_primary_key_value).compact.empty?

  Bullet.debug(
    'Detector::UnusedEagerLoading#add_eager_loadings',
    "objects: #{objects.map(&:bullet_key).join(', ')}, associations: #{associations}"
  )
  bullet_keys = objects.map(&:bullet_key)

  to_add = []
  to_merge = []
  to_delete = []
  eager_loadings.each do |k, _v|
    key_objects_overlap = k & bullet_keys

    next if key_objects_overlap.empty?

    bullet_keys -= k
    if key_objects_overlap == k
      to_add << [k, associations]
    else
      to_merge << [key_objects_overlap, (eager_loadings[k].dup << associations)]

      keys_without_objects = k - key_objects_overlap
      to_merge << [keys_without_objects, eager_loadings[k]]
      to_delete << k
    end
  end

  to_add.each { |k, val| eager_loadings.add k, val }
  to_merge.each { |k, val| eager_loadings.merge k, val }
  to_delete.each { |k| eager_loadings.delete k }

  eager_loadings.add bullet_keys, associations unless bullet_keys.empty?
end

.check_unused_preload_associationsObject

check if there are unused preload associations.

get related_objects from eager_loadings associated with object and associations
get call_object_association from associations of call_object_associations whose object is in related_objects
if association not in call_object_association, then the object => association - call_object_association is unused preload associations


17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/bullet/detector/unused_eager_loading.rb', line 17

def check_unused_preload_associations
  return unless Bullet.start?
  return unless Bullet.unused_eager_loading_enable?

  object_associations.each do |bullet_key, associations|
    object_association_diff = diff_object_associations bullet_key, associations
    next if object_association_diff.empty?

    Bullet.debug('detect unused preload', "object: #{bullet_key}, associations: #{object_association_diff}")
    create_notification(caller_in_project(bullet_key), bullet_key.bullet_class_name, object_association_diff)
  end
end