bullet 4.4.0 → 4.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,12 +1,14 @@
1
1
  module Bullet
2
2
  module Detector
3
- class UnusedEagerAssociation < Association
3
+ class UnusedEagerLoading < Association
4
4
  class <<self
5
5
  # check if there are unused preload associations.
6
6
  # get related_objects from eager_loadings associated with object and associations
7
7
  # get call_object_association from associations of call_object_associations whose object is in related_objects
8
8
  # if association not in call_object_association, then the object => association - call_object_association is ununsed preload assocations
9
9
  def check_unused_preload_associations
10
+ return unless Bullet.unused_eager_loading_enable?
11
+
10
12
  @@checked = true
11
13
  object_associations.each do |bullet_ar_key, associations|
12
14
  object_association_diff = diff_object_associations bullet_ar_key, associations
@@ -16,10 +18,45 @@ module Bullet
16
18
  end
17
19
  end
18
20
 
21
+ def add_eager_loadings(objects, associations)
22
+ return unless Bullet.unused_eager_loading_enable?
23
+ bullet_ar_keys = objects.map(&:bullet_ar_key)
24
+
25
+ to_add = nil
26
+ to_merge, to_delete = [], []
27
+ eager_loadings.each do |k, v|
28
+ key_objects_overlap = k & bullet_ar_keys
29
+
30
+ next if key_objects_overlap.empty?
31
+
32
+ if key_objects_overlap == k
33
+ to_add = [k, associations]
34
+ break
35
+ else
36
+ to_merge << [key_objects_overlap, ( eager_loadings[k].dup << associations )]
37
+
38
+ keys_without_objects = k - bullet_ar_keys
39
+ to_merge << [keys_without_objects, eager_loadings[k]]
40
+ to_delete << k
41
+ bullet_ar_keys = bullet_ar_keys - k
42
+ end
43
+ end
44
+
45
+ eager_loadings.add *to_add if to_add
46
+ to_merge.each { |k,val| eager_loadings.merge k, val }
47
+ to_delete.each { |k| eager_loadings.delete k }
48
+
49
+ eager_loadings.add bullet_ar_keys, associations unless bullet_ar_keys.empty?
50
+ end
51
+
19
52
  private
20
53
  def create_notification(klazz, associations)
21
- notice = Bullet::Notification::UnusedEagerLoading.new(klazz, associations)
22
- Bullet.notification_collector.add(notice)
54
+ notify_associations = Array(associations) - Bullet.get_whitelist_associations(:unused_eager_loading, klazz)
55
+
56
+ if notify_associations.present?
57
+ notice = Bullet::Notification::UnusedEagerLoading.new(klazz, notify_associations)
58
+ Bullet.notification_collector.add(notice)
59
+ end
23
60
  end
24
61
 
25
62
  def call_associations(bullet_ar_key, associations)
@@ -11,22 +11,22 @@ module Bullet
11
11
 
12
12
  def first
13
13
  result = origin_first
14
- Bullet::Detector::Association.add_impossible_object(result) if result
14
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(result) if result
15
15
  result
16
16
  end
17
17
 
18
18
  def last
19
19
  result = origin_last
20
- Bullet::Detector::Association.add_impossible_object(result) if result
20
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(result) if result
21
21
  result
22
22
  end
23
23
 
24
24
  def iterate(&block)
25
25
  records = execute.to_a
26
26
  if records.size > 1
27
- Bullet::Detector::Association.add_possible_objects(records)
27
+ Bullet::Detector::NPlusOneQuery.add_possible_objects(records)
28
28
  elsif records.size == 1
29
- Bullet::Detector::Association.add_impossible_object(records.first)
29
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(records.first)
30
30
  end
31
31
  origin_iterate(&block)
32
32
  end
@@ -36,7 +36,7 @@ module Bullet
36
36
  docs.each do |doc|
37
37
  Bullet::Detector::Association.add_object_associations(doc, associations)
38
38
  end
39
- Bullet::Detector::Association.add_eager_loadings(docs, associations)
39
+ Bullet::Detector::UnusedEagerLoading.add_eager_loadings(docs, associations)
40
40
  origin_eager_load(docs)
41
41
  end
42
42
  end
@@ -10,22 +10,22 @@ module Bullet
10
10
 
11
11
  def first
12
12
  result = origin_first
13
- Bullet::Detector::Association.add_impossible_object(result) if result
13
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(result) if result
14
14
  result
15
15
  end
16
16
 
17
17
  def last
18
18
  result = origin_last
19
- Bullet::Detector::Association.add_impossible_object(result) if result
19
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(result) if result
20
20
  result
21
21
  end
22
22
 
23
23
  def each(&block)
24
24
  records = query.map{ |doc| ::Mongoid::Factory.from_db(klass, doc) }
25
25
  if records.length > 1
26
- Bullet::Detector::Association.add_possible_objects(records)
26
+ Bullet::Detector::NPlusOneQuery.add_possible_objects(records)
27
27
  elsif records.size == 1
28
- Bullet::Detector::Association.add_impossible_object(records.first)
28
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(records.first)
29
29
  end
30
30
  origin_each(&block)
31
31
  end
@@ -33,9 +33,9 @@ module Bullet
33
33
  def eager_load(docs)
34
34
  associations = criteria.inclusions.map(&:name)
35
35
  docs.each do |doc|
36
- Bullet::Detector::Association.add_object_associations(doc, associations)
36
+ Bullet::Detector::NPlusOneQuery.add_object_associations(doc, associations)
37
37
  end
38
- Bullet::Detector::Association.add_eager_loadings(docs, associations)
38
+ Bullet::Detector::UnusedEagerLoading.add_eager_loadings(docs, associations)
39
39
  origin_eager_load(docs)
40
40
  end
41
41
  end
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module Bullet
3
- VERSION = "4.4.0"
3
+ VERSION = "4.5.0"
4
4
  end
@@ -40,55 +40,6 @@ module Bullet
40
40
  Association.send(:call_object_associations).should be_include(@post1.bullet_ar_key, :associations)
41
41
  end
42
42
  end
43
-
44
- context ".add_possible_objects" do
45
- it "should add possible objects" do
46
- Association.add_possible_objects([@post1, @post2])
47
- Association.send(:possible_objects).should be_include(@post1.bullet_ar_key)
48
- Association.send(:possible_objects).should be_include(@post2.bullet_ar_key)
49
- end
50
-
51
- it "should not raise error if object is nil" do
52
- lambda { Association.add_possible_objects(nil) }.should_not raise_error
53
- end
54
- end
55
-
56
- context ".add_impossible_object" do
57
- it "should add impossible object" do
58
- Association.add_impossible_object(@post1)
59
- Association.send(:impossible_objects).should be_include(@post1.bullet_ar_key)
60
- end
61
- end
62
-
63
- context ".add_eager_loadings" do
64
- it "should add objects, associations pair when eager_loadings are empty" do
65
- Association.add_eager_loadings([@post1, @post2], :associations)
66
- Association.send(:eager_loadings).should be_include([@post1.bullet_ar_key, @post2.bullet_ar_key], :associations)
67
- end
68
-
69
- it "should add objects, associations pair for existing eager_loadings" do
70
- Association.add_eager_loadings([@post1, @post2], :association1)
71
- Association.add_eager_loadings([@post1, @post2], :association2)
72
- Association.send(:eager_loadings).should be_include([@post1.bullet_ar_key, @post2.bullet_ar_key], :association1)
73
- Association.send(:eager_loadings).should be_include([@post1.bullet_ar_key, @post2.bullet_ar_key], :association2)
74
- end
75
-
76
- it "should merge objects, associations pair for existing eager_loadings" do
77
- Association.add_eager_loadings([@post1], :association1)
78
- Association.add_eager_loadings([@post1, @post2], :association2)
79
- Association.send(:eager_loadings).should be_include([@post1.bullet_ar_key], :association1)
80
- Association.send(:eager_loadings).should be_include([@post1.bullet_ar_key], :association2)
81
- Association.send(:eager_loadings).should be_include([@post1.bullet_ar_key, @post2.bullet_ar_key], :association2)
82
- end
83
-
84
- it "should delete objects, associations pair for existing eager_loadings" do
85
- Association.add_eager_loadings([@post1, @post2], :association1)
86
- Association.add_eager_loadings([@post1], :association2)
87
- Association.send(:eager_loadings).should be_include([@post1.bullet_ar_key], :association1)
88
- Association.send(:eager_loadings).should be_include([@post1.bullet_ar_key], :association2)
89
- Association.send(:eager_loadings).should be_include([@post2.bullet_ar_key], :association1)
90
- end
91
- end
92
43
  end
93
44
  end
94
45
  end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+
3
+ module Bullet
4
+ module Detector
5
+ describe CounterCache do
6
+ before :all do
7
+ @post1 = Post.first
8
+ @post2 = Post.last
9
+ end
10
+ before(:each) { CounterCache.clear }
11
+
12
+ context ".clear" do
13
+ it "should clear all class variables" do
14
+ CounterCache.class_variable_get(:@@possible_objects).should be_nil
15
+ CounterCache.class_variable_get(:@@impossible_objects).should be_nil
16
+ end
17
+ end
18
+
19
+ context ".add_counter_cache" do
20
+ it "should create notification if conditions met" do
21
+ CounterCache.should_receive(:conditions_met?).with(@post1.bullet_ar_key, [:comments]).and_return(true)
22
+ CounterCache.should_receive(:create_notification).with("Post", [:comments])
23
+ CounterCache.add_counter_cache(@post1, [:comments])
24
+ end
25
+
26
+ it "should not create notification if conditions not met" do
27
+ CounterCache.should_receive(:conditions_met?).with(@post1.bullet_ar_key, [:comments]).and_return(false)
28
+ CounterCache.should_receive(:create_notification).never
29
+ CounterCache.add_counter_cache(@post1, [:comments])
30
+ end
31
+ end
32
+
33
+ context ".add_possible_objects" do
34
+ it "should add possible objects" do
35
+ CounterCache.add_possible_objects([@post1, @post2])
36
+ CounterCache.send(:possible_objects).should be_include(@post1.bullet_ar_key)
37
+ CounterCache.send(:possible_objects).should be_include(@post2.bullet_ar_key)
38
+ end
39
+
40
+ it "should add impossible object" do
41
+ CounterCache.add_impossible_object(@post1)
42
+ CounterCache.send(:impossible_objects).should be_include(@post1.bullet_ar_key)
43
+ end
44
+ end
45
+
46
+ context ".conditions_met?" do
47
+ it "should be true when object is possible, not impossible" do
48
+ CounterCache.add_possible_objects(@post1)
49
+ CounterCache.send(:conditions_met?, @post1.bullet_ar_key, :associations).should be_true
50
+ end
51
+
52
+ it "should be false when object is not possible" do
53
+ CounterCache.send(:conditions_met?, @post1.bullet_ar_key, :associations).should be_false
54
+ end
55
+
56
+ it "should be true when object is possible, and impossible" do
57
+ CounterCache.add_possible_objects(@post1)
58
+ CounterCache.add_impossible_object(@post1)
59
+ CounterCache.send(:conditions_met?, @post1.bullet_ar_key, :associations).should be_false
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -3,7 +3,10 @@ require 'spec_helper'
3
3
  module Bullet
4
4
  module Detector
5
5
  describe NPlusOneQuery do
6
- before(:all) { @post = Post.first }
6
+ before(:all) do
7
+ @post = Post.first
8
+ @post2 = Post.last
9
+ end
7
10
  before(:each) { NPlusOneQuery.clear }
8
11
 
9
12
  context ".call_association" do
@@ -89,6 +92,25 @@ module Bullet
89
92
  NPlusOneQuery.call_association(@post, :association)
90
93
  end
91
94
  end
95
+
96
+ context ".add_possible_objects" do
97
+ it "should add possible objects" do
98
+ NPlusOneQuery.add_possible_objects([@post, @post2])
99
+ NPlusOneQuery.send(:possible_objects).should be_include(@post.bullet_ar_key)
100
+ NPlusOneQuery.send(:possible_objects).should be_include(@post2.bullet_ar_key)
101
+ end
102
+
103
+ it "should not raise error if object is nil" do
104
+ lambda { NPlusOneQuery.add_possible_objects(nil) }.should_not raise_error
105
+ end
106
+ end
107
+
108
+ context ".add_impossible_object" do
109
+ it "should add impossible object" do
110
+ NPlusOneQuery.add_impossible_object(@post)
111
+ NPlusOneQuery.send(:impossible_objects).should be_include(@post.bullet_ar_key)
112
+ end
113
+ end
92
114
  end
93
115
  end
94
116
  end
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+
3
+ module Bullet
4
+ module Detector
5
+ describe UnusedEagerLoading do
6
+ before(:all) do
7
+ @post = Post.first
8
+ @post2 = Post.last
9
+ end
10
+ before(:each) { UnusedEagerLoading.clear }
11
+
12
+ context ".call_associations" do
13
+ it "should get empty array if eager_loadgins" do
14
+ UnusedEagerLoading.send(:call_associations, @post.bullet_ar_key, Set.new([:association])).should be_empty
15
+ end
16
+
17
+ it "should get call associations if object and association are both in eager_loadings and call_object_associations" do
18
+ UnusedEagerLoading.add_eager_loadings([@post], :association)
19
+ UnusedEagerLoading.add_call_object_associations(@post, :association)
20
+ UnusedEagerLoading.send(:call_associations, @post.bullet_ar_key, Set.new([:association])).should == [:association]
21
+ end
22
+
23
+ it "should not get call associations if not exist in call_object_associations" do
24
+ UnusedEagerLoading.add_eager_loadings([@post], :association)
25
+ UnusedEagerLoading.send(:call_associations, @post.bullet_ar_key, Set.new([:association])).should be_empty
26
+ end
27
+ end
28
+
29
+ context ".diff_object_associations" do
30
+ it "should return associations not exist in call_association" do
31
+ UnusedEagerLoading.send(:diff_object_associations, @post.bullet_ar_key, Set.new([:association])).should == [:association]
32
+ end
33
+
34
+ it "should return empty if associations exist in call_association" do
35
+ UnusedEagerLoading.add_eager_loadings([@post], :association)
36
+ UnusedEagerLoading.add_call_object_associations(@post, :association)
37
+ UnusedEagerLoading.send(:diff_object_associations, @post.bullet_ar_key, Set.new([:association])).should be_empty
38
+ end
39
+ end
40
+
41
+ context ".check_unused_preload_associations" do
42
+ it "should set @@checked to true" do
43
+ UnusedEagerLoading.check_unused_preload_associations
44
+ UnusedEagerLoading.class_variable_get(:@@checked).should be_true
45
+ end
46
+
47
+ it "should create notification if object_association_diff is not empty" do
48
+ UnusedEagerLoading.add_object_associations(@post, :association)
49
+ UnusedEagerLoading.should_receive(:create_notification).with("Post", [:association])
50
+ UnusedEagerLoading.check_unused_preload_associations
51
+ end
52
+
53
+ it "should not create notification if object_association_diff is empty" do
54
+ UnusedEagerLoading.clear
55
+ UnusedEagerLoading.add_object_associations(@post, :association)
56
+ UnusedEagerLoading.add_eager_loadings([@post], :association)
57
+ UnusedEagerLoading.add_call_object_associations(@post, :association)
58
+ UnusedEagerLoading.send(:diff_object_associations, @post.bullet_ar_key, Set.new([:association])).should be_empty
59
+ UnusedEagerLoading.should_not_receive(:create_notification).with("Post", [:association])
60
+ UnusedEagerLoading.check_unused_preload_associations
61
+ end
62
+ end
63
+
64
+ context ".add_eager_loadings" do
65
+ it "should add objects, associations pair when eager_loadings are empty" do
66
+ UnusedEagerLoading.add_eager_loadings([@post, @post2], :associations)
67
+ UnusedEagerLoading.send(:eager_loadings).should be_include([@post.bullet_ar_key, @post2.bullet_ar_key], :associations)
68
+ end
69
+
70
+ it "should add objects, associations pair for existing eager_loadings" do
71
+ UnusedEagerLoading.add_eager_loadings([@post, @post2], :association1)
72
+ UnusedEagerLoading.add_eager_loadings([@post, @post2], :association2)
73
+ UnusedEagerLoading.send(:eager_loadings).should be_include([@post.bullet_ar_key, @post2.bullet_ar_key], :association1)
74
+ UnusedEagerLoading.send(:eager_loadings).should be_include([@post.bullet_ar_key, @post2.bullet_ar_key], :association2)
75
+ end
76
+
77
+ it "should merge objects, associations pair for existing eager_loadings" do
78
+ UnusedEagerLoading.add_eager_loadings([@post], :association1)
79
+ UnusedEagerLoading.add_eager_loadings([@post, @post2], :association2)
80
+ UnusedEagerLoading.send(:eager_loadings).should be_include([@post.bullet_ar_key], :association1)
81
+ UnusedEagerLoading.send(:eager_loadings).should be_include([@post.bullet_ar_key], :association2)
82
+ UnusedEagerLoading.send(:eager_loadings).should be_include([@post.bullet_ar_key, @post2.bullet_ar_key], :association2)
83
+ end
84
+
85
+ it "should delete objects, associations pair for existing eager_loadings" do
86
+ UnusedEagerLoading.add_eager_loadings([@post, @post2], :association1)
87
+ UnusedEagerLoading.add_eager_loadings([@post], :association2)
88
+ UnusedEagerLoading.send(:eager_loadings).should be_include([@post.bullet_ar_key], :association1)
89
+ UnusedEagerLoading.send(:eager_loadings).should be_include([@post.bullet_ar_key], :association2)
90
+ UnusedEagerLoading.send(:eager_loadings).should be_include([@post2.bullet_ar_key], :association1)
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -16,7 +16,7 @@ if active_record3? || active_record4?
16
16
  Post.all.each do |post|
17
17
  post.comments.map(&:name)
18
18
  end
19
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
19
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
20
20
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
21
21
 
22
22
  Bullet::Detector::Association.should be_detecting_unpreloaded_association_for(Post, :comments)
@@ -26,7 +26,7 @@ if active_record3? || active_record4?
26
26
  Post.includes(:comments).each do |post|
27
27
  post.comments.map(&:name)
28
28
  end
29
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
29
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
30
30
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
31
31
 
32
32
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -34,7 +34,7 @@ if active_record3? || active_record4?
34
34
 
35
35
  it "should detect unused preload post => comments" do
36
36
  Post.includes(:comments).map(&:name)
37
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
37
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
38
38
  Bullet::Detector::Association.should be_unused_preload_associations_for(Post, :comments)
39
39
 
40
40
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -42,7 +42,7 @@ if active_record3? || active_record4?
42
42
 
43
43
  it "should not detect unused preload post => comments" do
44
44
  Post.all.map(&:name)
45
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
45
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
46
46
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
47
47
 
48
48
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -56,7 +56,7 @@ if active_record3? || active_record4?
56
56
  post.comments.map(&:name)
57
57
  end
58
58
  end
59
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
59
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
60
60
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
61
61
 
62
62
  Bullet::Detector::Association.should be_detecting_unpreloaded_association_for(Category, :posts)
@@ -69,7 +69,7 @@ if active_record3? || active_record4?
69
69
  post.comments.map(&:name)
70
70
  end
71
71
  end
72
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
72
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
73
73
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
74
74
 
75
75
  Bullet::Detector::Association.should_not be_detecting_unpreloaded_association_for(Category, :posts)
@@ -82,7 +82,7 @@ if active_record3? || active_record4?
82
82
  post.comments.map(&:name)
83
83
  end
84
84
  end
85
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
85
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
86
86
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
87
87
 
88
88
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -90,7 +90,7 @@ if active_record3? || active_record4?
90
90
 
91
91
  it "should detect unused preload with category => posts => comments" do
92
92
  Category.includes({:posts => :comments}).map(&:name)
93
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
93
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
94
94
  Bullet::Detector::Association.should be_unused_preload_associations_for(Post, :comments)
95
95
 
96
96
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -100,7 +100,7 @@ if active_record3? || active_record4?
100
100
  Category.includes({:posts => :comments}).each do |category|
101
101
  category.posts.map(&:name)
102
102
  end
103
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
103
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
104
104
  Bullet::Detector::Association.should be_unused_preload_associations_for(Post, :comments)
105
105
 
106
106
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -113,7 +113,7 @@ if active_record3? || active_record4?
113
113
  category.posts.map(&:name)
114
114
  category.entries.map(&:name)
115
115
  end
116
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
116
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
117
117
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
118
118
 
119
119
  Bullet::Detector::Association.should be_detecting_unpreloaded_association_for(Category, :posts)
@@ -125,7 +125,7 @@ if active_record3? || active_record4?
125
125
  category.posts.map(&:name)
126
126
  category.entries.map(&:name)
127
127
  end
128
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
128
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
129
129
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
130
130
 
131
131
  Bullet::Detector::Association.should_not be_detecting_unpreloaded_association_for(Category, :posts)
@@ -137,7 +137,7 @@ if active_record3? || active_record4?
137
137
  category.posts.map(&:name)
138
138
  category.entries.map(&:name)
139
139
  end
140
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
140
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
141
141
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
142
142
 
143
143
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -145,7 +145,7 @@ if active_record3? || active_record4?
145
145
 
146
146
  it "should detect unused preload with category => [posts, entries]" do
147
147
  Category.includes([:posts, :entries]).map(&:name)
148
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
148
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
149
149
  Bullet::Detector::Association.should be_unused_preload_associations_for(Category, :posts)
150
150
  Bullet::Detector::Association.should be_unused_preload_associations_for(Category, :entries)
151
151
 
@@ -156,7 +156,7 @@ if active_record3? || active_record4?
156
156
  Category.includes([:posts, :entries]).each do |category|
157
157
  category.posts.map(&:name)
158
158
  end
159
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
159
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
160
160
  Bullet::Detector::Association.should_not be_unused_preload_associations_for(Category, :posts)
161
161
  Bullet::Detector::Association.should be_unused_preload_associations_for(Category, :entries)
162
162
 
@@ -169,7 +169,7 @@ if active_record3? || active_record4?
169
169
  Post.includes(:comments).each do |post|
170
170
  post.comments.first.name
171
171
  end
172
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
172
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
173
173
  Bullet::Detector::Association.should_not be_unused_preload_associations_for(Post, :comments)
174
174
 
175
175
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -177,7 +177,7 @@ if active_record3? || active_record4?
177
177
 
178
178
  it "should detect preload with post => commnets" do
179
179
  Post.first.comments.map(&:name)
180
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
180
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
181
181
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
182
182
 
183
183
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -191,7 +191,7 @@ if active_record3? || active_record4?
191
191
  post.name
192
192
  post.writer.name
193
193
  end
194
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
194
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
195
195
  Bullet::Detector::Association.should_not be_unused_preload_associations_for(Category, :posts)
196
196
  Bullet::Detector::Association.should_not be_unused_preload_associations_for(Post, :writer)
197
197
  end
@@ -202,7 +202,7 @@ if active_record3? || active_record4?
202
202
  Post.in_category_name('first').each do |post|
203
203
  post.category.name
204
204
  end
205
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
205
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
206
206
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
207
207
 
208
208
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -210,7 +210,7 @@ if active_record3? || active_record4?
210
210
 
211
211
  it "should not be unused preload post => category" do
212
212
  Post.in_category_name('first').all.map(&:name)
213
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
213
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
214
214
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
215
215
 
216
216
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -222,7 +222,7 @@ if active_record3? || active_record4?
222
222
  Post.preload_comments.each do |post|
223
223
  post.comments.map(&:name)
224
224
  end
225
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
225
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
226
226
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
227
227
 
228
228
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -230,7 +230,7 @@ if active_record3? || active_record4?
230
230
 
231
231
  it "should detect unused preload with scope" do
232
232
  Post.preload_comments.map(&:name)
233
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
233
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
234
234
  Bullet::Detector::Association.should be_unused_preload_associations_for(Post, :comments)
235
235
 
236
236
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -253,7 +253,7 @@ if active_record3? || active_record4?
253
253
  Comment.all.each do |comment|
254
254
  comment.post.name
255
255
  end
256
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
256
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
257
257
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
258
258
 
259
259
  Bullet::Detector::Association.should be_detecting_unpreloaded_association_for(Comment, :post)
@@ -261,7 +261,7 @@ if active_record3? || active_record4?
261
261
 
262
262
  it "should detect preload with one comment => post" do
263
263
  Comment.first.post.name
264
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
264
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
265
265
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
266
266
 
267
267
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -271,7 +271,7 @@ if active_record3? || active_record4?
271
271
  Comment.includes(:post).each do |comment|
272
272
  comment.post.name
273
273
  end
274
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
274
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
275
275
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
276
276
 
277
277
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -279,7 +279,7 @@ if active_record3? || active_record4?
279
279
 
280
280
  it "should not detect preload with comment => post" do
281
281
  Comment.all.map(&:name)
282
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
282
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
283
283
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
284
284
 
285
285
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -287,7 +287,7 @@ if active_record3? || active_record4?
287
287
 
288
288
  it "should detect unused preload with comments => post" do
289
289
  Comment.includes(:post).map(&:name)
290
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
290
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
291
291
  Bullet::Detector::Association.should be_unused_preload_associations_for(Comment, :post)
292
292
 
293
293
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -299,7 +299,7 @@ if active_record3? || active_record4?
299
299
  Comment.all.each do |comment|
300
300
  comment.post.category.name
301
301
  end
302
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
302
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
303
303
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
304
304
 
305
305
  Bullet::Detector::Association.should be_detecting_unpreloaded_association_for(Comment, :post)
@@ -309,7 +309,7 @@ if active_record3? || active_record4?
309
309
  Comment.includes(:post).each do |comment|
310
310
  comment.post.category.name
311
311
  end
312
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
312
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
313
313
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
314
314
 
315
315
  Bullet::Detector::Association.should be_detecting_unpreloaded_association_for(Post, :category)
@@ -319,7 +319,7 @@ if active_record3? || active_record4?
319
319
  Comment.includes(:post => :category).each do |comment|
320
320
  comment.post.category.name
321
321
  end
322
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
322
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
323
323
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
324
324
 
325
325
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -333,7 +333,7 @@ if active_record3? || active_record4?
333
333
  Comment.includes([:author, :post]).where(["base_users.id = ?", BaseUser.first]).each do |comment|
334
334
  comment.post.writer.name
335
335
  end
336
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
336
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
337
337
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
338
338
 
339
339
  Bullet::Detector::Association.should be_detecting_unpreloaded_association_for(Post, :writer)
@@ -345,7 +345,7 @@ if active_record3? || active_record4?
345
345
  Comment.includes([:author, {:post => :writer}]).where(["base_users.id = ?", BaseUser.first]).each do |comment|
346
346
  comment.post.writer.name
347
347
  end
348
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
348
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
349
349
  Bullet::Detector::Association.should be_unused_preload_associations_for(Comment, :author)
350
350
 
351
351
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -357,7 +357,7 @@ if active_record3? || active_record4?
357
357
  Comment.all(:include => {:post => :writer}, :conditions => "posts.name like '%first%'").each do |comment|
358
358
  comment.post.writer.newspaper.name
359
359
  end
360
- #Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
360
+ #Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
361
361
  #Bullet::Detector::Association.should_not be_has_unused_preload_associations
362
362
 
363
363
  Bullet::Detector::Association.should be_detecting_unpreloaded_association_for(Writer, :newspaper)
@@ -390,7 +390,7 @@ if active_record3? || active_record4?
390
390
  Student.all.each do |student|
391
391
  student.teachers.map(&:name)
392
392
  end
393
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
393
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
394
394
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
395
395
 
396
396
  Bullet::Detector::Association.should be_detecting_unpreloaded_association_for(Student, :teachers)
@@ -400,7 +400,7 @@ if active_record3? || active_record4?
400
400
  Student.includes(:teachers).each do |student|
401
401
  student.teachers.map(&:name)
402
402
  end
403
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
403
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
404
404
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
405
405
 
406
406
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -408,7 +408,7 @@ if active_record3? || active_record4?
408
408
 
409
409
  it "should detect unused preload associations" do
410
410
  Student.includes(:teachers).map(&:name)
411
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
411
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
412
412
  Bullet::Detector::Association.should be_unused_preload_associations_for(Student, :teachers)
413
413
 
414
414
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -416,7 +416,7 @@ if active_record3? || active_record4?
416
416
 
417
417
  it "should detect no unused preload associations" do
418
418
  Student.all.map(&:name)
419
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
419
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
420
420
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
421
421
 
422
422
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -439,7 +439,7 @@ if active_record3? || active_record4?
439
439
  Firm.all.each do |firm|
440
440
  firm.clients.map(&:name)
441
441
  end
442
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
442
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
443
443
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
444
444
 
445
445
  Bullet::Detector::Association.should be_detecting_unpreloaded_association_for(Firm, :clients)
@@ -449,7 +449,7 @@ if active_record3? || active_record4?
449
449
  Firm.includes(:clients).each do |firm|
450
450
  firm.clients.map(&:name)
451
451
  end
452
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
452
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
453
453
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
454
454
 
455
455
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -457,7 +457,7 @@ if active_record3? || active_record4?
457
457
 
458
458
  it "should not detect preload associations" do
459
459
  Firm.all.map(&:name)
460
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
460
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
461
461
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
462
462
 
463
463
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -465,7 +465,7 @@ if active_record3? || active_record4?
465
465
 
466
466
  it "should detect unused preload associations" do
467
467
  Firm.includes(:clients).map(&:name)
468
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
468
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
469
469
  Bullet::Detector::Association.should be_unused_preload_associations_for(Firm, :clients)
470
470
 
471
471
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -488,7 +488,7 @@ if active_record3? || active_record4?
488
488
  Company.all.each do |company|
489
489
  company.address.name
490
490
  end
491
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
491
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
492
492
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
493
493
 
494
494
  Bullet::Detector::Association.should be_detecting_unpreloaded_association_for(Company, :address)
@@ -498,7 +498,7 @@ if active_record3? || active_record4?
498
498
  Company.includes(:address).each do |company|
499
499
  company.address.name
500
500
  end
501
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
501
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
502
502
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
503
503
 
504
504
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -506,7 +506,7 @@ if active_record3? || active_record4?
506
506
 
507
507
  it "should not detect preload association" do
508
508
  Company.all.map(&:name)
509
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
509
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
510
510
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
511
511
 
512
512
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -514,7 +514,7 @@ if active_record3? || active_record4?
514
514
 
515
515
  it "should detect unused preload association" do
516
516
  Company.includes(:address).map(&:name)
517
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
517
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
518
518
  Bullet::Detector::Association.should be_unused_preload_associations_for(Company, :address)
519
519
 
520
520
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -535,7 +535,7 @@ if active_record3? || active_record4?
535
535
  it "should not detect preload association" do
536
536
  Post.all
537
537
  Post.first.comments.map(&:name)
538
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
538
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
539
539
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
540
540
 
541
541
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -557,7 +557,7 @@ if active_record3? || active_record4?
557
557
  Page.all.each do |page|
558
558
  page.author.name
559
559
  end
560
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
560
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
561
561
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
562
562
 
563
563
  Bullet::Detector::Association.should be_detecting_unpreloaded_association_for(Page, :author)
@@ -567,7 +567,7 @@ if active_record3? || active_record4?
567
567
  Page.includes(:author).each do |page|
568
568
  page.author.name
569
569
  end
570
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
570
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
571
571
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
572
572
 
573
573
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -575,7 +575,7 @@ if active_record3? || active_record4?
575
575
 
576
576
  it "should detect unused preload associations" do
577
577
  Page.includes(:author).map(&:name)
578
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
578
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
579
579
  Bullet::Detector::Association.should be_unused_preload_associations_for(Page, :author)
580
580
 
581
581
  Bullet::Detector::Association.should be_completely_preloading_associations
@@ -583,11 +583,103 @@ if active_record3? || active_record4?
583
583
 
584
584
  it "should not detect preload associations" do
585
585
  Page.all.map(&:name)
586
- Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
586
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
587
587
  Bullet::Detector::Association.should_not be_has_unused_preload_associations
588
588
 
589
589
  Bullet::Detector::Association.should be_completely_preloading_associations
590
590
  end
591
591
  end
592
+
593
+ context "disable n plus one query" do
594
+ before { Bullet.n_plus_one_query_enable = false }
595
+ after { Bullet.n_plus_one_query_enable = true }
596
+
597
+ it "should not detect n plus one query" do
598
+ Post.all.each do |post|
599
+ post.comments.map(&:name)
600
+ end
601
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
602
+
603
+ expect(Bullet::Detector::Association).not_to be_detecting_unpreloaded_association_for(Post, :comments)
604
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
605
+ end
606
+
607
+ it "should still detect unused eager loading" do
608
+ Post.includes(:comments).map(&:name)
609
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
610
+
611
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
612
+ expect(Bullet::Detector::Association).to be_unused_preload_associations_for(Post, :comments)
613
+ end
614
+ end
615
+
616
+ context "disable unused eager loading" do
617
+ before { Bullet.unused_eager_loading_enable = false }
618
+ after { Bullet.unused_eager_loading_enable = true }
619
+
620
+ it "should not detect unused eager loading" do
621
+ Post.includes(:comments).map(&:name)
622
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
623
+
624
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
625
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
626
+ end
627
+
628
+ it "should still detect n plus one query" do
629
+ Post.all.each do |post|
630
+ post.comments.map(&:name)
631
+ end
632
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
633
+
634
+ expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Post, :comments)
635
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
636
+ end
637
+ end
638
+
639
+ context "whitelist n plus one query" do
640
+ before { Bullet.add_whitelist :type => :n_plus_one_query, :class_name => "Post", :association => :comments }
641
+ after { Bullet.reset_whitelist }
642
+
643
+ it "should not detect n plus one query" do
644
+ Post.all.each do |post|
645
+ post.comments.map(&:name)
646
+ end
647
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
648
+
649
+ expect(Bullet::Detector::Association).not_to be_detecting_unpreloaded_association_for(Post, :comments)
650
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
651
+ end
652
+
653
+ it "should still detect unused eager loading" do
654
+ Post.includes(:comments).map(&:name)
655
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
656
+
657
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
658
+ expect(Bullet::Detector::Association).to be_unused_preload_associations_for(Post, :comments)
659
+ end
660
+ end
661
+
662
+ context "whitelist unused eager loading" do
663
+ before { Bullet.add_whitelist :type => :unused_eager_loading, :class_name => "Post", :association => :comments }
664
+ after { Bullet.reset_whitelist }
665
+
666
+ it "should not detect unused eager loading" do
667
+ Post.includes(:comments).map(&:name)
668
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
669
+
670
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
671
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
672
+ end
673
+
674
+ it "should still detect n plus one query" do
675
+ Post.all.each do |post|
676
+ post.comments.map(&:name)
677
+ end
678
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
679
+
680
+ expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Post, :comments)
681
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
682
+ end
683
+ end
592
684
  end
593
685
  end