module Bullet module Detector class NPlusOneQuery < Association extend Dependency class < associations already exists in object_associations. def association?(object, associations) value = object_associations[object.bullet_key] if value value.each do |v| # associations == v comparision 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 private 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 def caller_in_project app_root = rails? ? Rails.root.to_s : Dir.pwd vendor_root = app_root + "/vendor" caller.select do |c| c.include?(app_root) && !c.include?(vendor_root) || Bullet.stacktrace_includes.any? { |include| c.include?(include) } end end def excluded_stacktrace_path? Bullet.stacktrace_excludes.any? do |excluded_path| caller_in_project.any? { |c| c.include?(excluded_path) } end end end end end end