class Bullet::Detector::NPlusOneQuery
Public Class Methods
add_impossible_object(object)
click to toggle source
# File lib/bullet/detector/n_plus_one_query.rb, line 38 def add_impossible_object(object) return unless Bullet.start? return unless Bullet.n_plus_one_query_enable? return unless object.primary_key_value Bullet.debug('Detector::NPlusOneQuery#add_impossible_object'.freeze, "object: #{object.bullet_key}") impossible_objects.add object.bullet_key end
add_inversed_object(object, association)
click to toggle source
# File lib/bullet/detector/n_plus_one_query.rb, line 47 def add_inversed_object(object, association) return unless Bullet.start? return unless Bullet.n_plus_one_query_enable? return unless object.primary_key_value Bullet.debug('Detector::NPlusOneQuery#add_inversed_object'.freeze, "object: #{object.bullet_key}, association: #{association}") inversed_objects.add object.bullet_key, association end
add_possible_objects(object_or_objects)
click to toggle source
# File lib/bullet/detector/n_plus_one_query.rb, line 28 def add_possible_objects(object_or_objects) return unless Bullet.start? return unless Bullet.n_plus_one_query_enable? objects = Array(object_or_objects) return if objects.map(&:primary_key_value).compact.empty? Bullet.debug('Detector::NPlusOneQuery#add_possible_objects'.freeze, "objects: #{objects.map(&:bullet_key).join(', '.freeze)}") objects.each { |object| possible_objects.add object.bullet_key } end
association?(object, associations)
click to toggle source
check if object => associations already exists in object_associations.
# File lib/bullet/detector/n_plus_one_query.rb, line 70 def association?(object, associations) value = object_associations[object.bullet_key] if value value.each do |v| # associations == v comparison order is important here because # v variable might be a squeel node where :== method is redefined, # so it does not compare values at all and return unexpected results result = v.is_a?(Hash) ? v.key?(associations) : associations == v return true if result end end false end
call_association(object, associations)
click to toggle source
executed when object.assocations is called. first, it keeps this method call for object.association. then, it checks if this associations call is unpreload.
if it is, keeps this unpreload associations and caller.
# File lib/bullet/detector/n_plus_one_query.rb, line 14 def call_association(object, associations) return unless Bullet.start? return unless Bullet.n_plus_one_query_enable? return unless object.primary_key_value return if inversed_objects.include?(object.bullet_key, associations) add_call_object_associations(object, associations) Bullet.debug('Detector::NPlusOneQuery#call_association'.freeze, "object: #{object.bullet_key}, associations: #{associations}") if !excluded_stacktrace_path? && conditions_met?(object, associations) Bullet.debug('detect n + 1 query', "object: #{object.bullet_key}, associations: #{associations}") create_notification caller_in_project, object.class.to_s, associations end end
conditions_met?(object, associations)
click to toggle source
decide whether the object.associations is unpreloaded or not.
# File lib/bullet/detector/n_plus_one_query.rb, line 57 def conditions_met?(object, associations) possible?(object) && !impossible?(object) && !association?(object, associations) end
impossible?(object)
click to toggle source
# File lib/bullet/detector/n_plus_one_query.rb, line 65 def impossible?(object) impossible_objects.include? object.bullet_key end
possible?(object)
click to toggle source
# File lib/bullet/detector/n_plus_one_query.rb, line 61 def possible?(object) possible_objects.include? object.bullet_key end
Private Class Methods
create_notification(callers, klazz, associations)
click to toggle source
# File lib/bullet/detector/n_plus_one_query.rb, line 87 def create_notification(callers, klazz, associations) notify_associations = Array(associations) - Bullet.get_whitelist_associations(:n_plus_one_query, klazz) if notify_associations.present? notice = Bullet::Notification::NPlusOneQuery.new(callers, klazz, notify_associations) Bullet.notification_collector.add(notice) end end