bullet 4.14.4 → 4.14.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +26 -1
- data/CHANGELOG.md +14 -2
- data/Gemfile.mongoid +0 -2
- data/Gemfile.mongoid-2.4 +0 -2
- data/Gemfile.mongoid-2.5 +0 -2
- data/Gemfile.mongoid-2.6 +0 -2
- data/Gemfile.mongoid-2.7 +0 -2
- data/Gemfile.mongoid-2.8 +0 -2
- data/Gemfile.mongoid-3.0 +0 -2
- data/Gemfile.mongoid-3.1 +0 -2
- data/Gemfile.mongoid-4.0 +0 -2
- data/Gemfile.rails-3.1 +0 -2
- data/Gemfile.rails-3.2 +0 -2
- data/Gemfile.rails-4.0 +0 -2
- data/Gemfile.rails-4.1 +0 -2
- data/Gemfile.rails-4.2 +0 -2
- data/README.md +8 -1
- data/bullet.gemspec +1 -1
- data/lib/bullet/active_record3.rb +63 -35
- data/lib/bullet/active_record3x.rb +55 -33
- data/lib/bullet/active_record4.rb +51 -31
- data/lib/bullet/active_record41.rb +53 -32
- data/lib/bullet/active_record42.rb +80 -50
- data/lib/bullet/detector/association.rb +16 -16
- data/lib/bullet/detector/counter_cache.rb +13 -13
- data/lib/bullet/detector/n_plus_one_query.rb +30 -27
- data/lib/bullet/notification/n_plus_one_query.rb +6 -0
- data/lib/bullet/rack.rb +3 -5
- data/lib/bullet/version.rb +1 -1
- data/lib/bullet.rb +12 -7
- data/spec/bullet/detector/counter_cache_spec.rb +8 -8
- data/spec/bullet/detector/n_plus_one_query_spec.rb +27 -27
- data/spec/bullet/rack_spec.rb +2 -2
- data/spec/integration/active_record3/association_spec.rb +9 -0
- data/spec/integration/active_record4/association_spec.rb +9 -0
- metadata +7 -7
|
@@ -15,7 +15,7 @@ module Bullet
|
|
|
15
15
|
add_call_object_associations(object, associations)
|
|
16
16
|
|
|
17
17
|
Bullet.debug("Detector::NPlusOneQuery#call_association", "object: #{object.bullet_key}, associations: #{associations}")
|
|
18
|
-
if conditions_met?(object
|
|
18
|
+
if conditions_met?(object, associations)
|
|
19
19
|
Bullet.debug("detect n + 1 query", "object: #{object.bullet_key}, associations: #{associations}")
|
|
20
20
|
create_notification caller_in_project, object.class.to_s, associations
|
|
21
21
|
end
|
|
@@ -49,6 +49,35 @@ module Bullet
|
|
|
49
49
|
inversed_objects.add object.bullet_key, association
|
|
50
50
|
end
|
|
51
51
|
|
|
52
|
+
# decide whether the object.associations is unpreloaded or not.
|
|
53
|
+
def conditions_met?(object, associations)
|
|
54
|
+
possible?(object) && !impossible?(object) && !association?(object, associations)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def possible?(object)
|
|
58
|
+
possible_objects.include? object.bullet_key
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def impossible?(object)
|
|
62
|
+
impossible_objects.include? object.bullet_key
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# check if object => associations already exists in object_associations.
|
|
66
|
+
def association?(object, associations)
|
|
67
|
+
value = object_associations[object.bullet_key]
|
|
68
|
+
if value
|
|
69
|
+
value.each do |v|
|
|
70
|
+
# associations == v comparision order is important here because
|
|
71
|
+
# v variable might be a squeel node where :== method is redefined,
|
|
72
|
+
# so it does not compare values at all and return unexpected results
|
|
73
|
+
result = v.is_a?(Hash) ? v.has_key?(associations) : associations == v
|
|
74
|
+
return true if result
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
false
|
|
79
|
+
end
|
|
80
|
+
|
|
52
81
|
private
|
|
53
82
|
def create_notification(callers, klazz, associations)
|
|
54
83
|
notify_associations = Array(associations) - Bullet.get_whitelist_associations(:n_plus_one_query, klazz)
|
|
@@ -59,11 +88,6 @@ module Bullet
|
|
|
59
88
|
end
|
|
60
89
|
end
|
|
61
90
|
|
|
62
|
-
# decide whether the object.associations is unpreloaded or not.
|
|
63
|
-
def conditions_met?(bullet_key, associations)
|
|
64
|
-
possible?(bullet_key) && !impossible?(bullet_key) && !association?(bullet_key, associations)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
91
|
def caller_in_project
|
|
68
92
|
app_root = rails? ? Rails.root.to_s : Dir.pwd
|
|
69
93
|
vendor_root = app_root + "/vendor"
|
|
@@ -72,27 +96,6 @@ module Bullet
|
|
|
72
96
|
Bullet.stacktrace_includes.any? { |include| c.include?(include) }
|
|
73
97
|
end
|
|
74
98
|
end
|
|
75
|
-
|
|
76
|
-
def possible?(bullet_key)
|
|
77
|
-
possible_objects.include? bullet_key
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
def impossible?(bullet_key)
|
|
81
|
-
impossible_objects.include? bullet_key
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
# check if object => associations already exists in object_associations.
|
|
85
|
-
def association?(bullet_key, associations)
|
|
86
|
-
value = object_associations[bullet_key]
|
|
87
|
-
if value
|
|
88
|
-
value.each do |v|
|
|
89
|
-
result = v.is_a?(Hash) ? v.has_key?(associations) : v == associations
|
|
90
|
-
return true if result
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
return false
|
|
95
|
-
end
|
|
96
99
|
end
|
|
97
100
|
end
|
|
98
101
|
end
|
|
@@ -15,6 +15,12 @@ module Bullet
|
|
|
15
15
|
"N+1 Query #{@path ? "in #{@path}" : 'detected'}"
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
+
def notification_data
|
|
19
|
+
super.merge(
|
|
20
|
+
:backtrace => @callers
|
|
21
|
+
)
|
|
22
|
+
end
|
|
23
|
+
|
|
18
24
|
protected
|
|
19
25
|
def call_stack_messages
|
|
20
26
|
(['N+1 Query method call stack'] + @callers).join( "\n " )
|
data/lib/bullet/rack.rb
CHANGED
|
@@ -10,7 +10,7 @@ module Bullet
|
|
|
10
10
|
return @app.call(env) unless Bullet.enable?
|
|
11
11
|
Bullet.start_request
|
|
12
12
|
status, headers, response = @app.call(env)
|
|
13
|
-
return [status, headers, response] if file?(headers) || sse?(
|
|
13
|
+
return [status, headers, response] if file?(headers) || sse?(headers) || empty?(response)
|
|
14
14
|
|
|
15
15
|
response_body = nil
|
|
16
16
|
if Bullet.notification?
|
|
@@ -20,8 +20,6 @@ module Bullet
|
|
|
20
20
|
append_to_html_body(response_body, Bullet.gather_inline_notifications)
|
|
21
21
|
headers['Content-Length'] = response_body.bytesize.to_s
|
|
22
22
|
end
|
|
23
|
-
end
|
|
24
|
-
if Bullet.enable? && Bullet.notification?
|
|
25
23
|
Bullet.perform_out_of_channel_notifications(env)
|
|
26
24
|
end
|
|
27
25
|
[status, headers, response_body ? [response_body] : response]
|
|
@@ -60,8 +58,8 @@ module Bullet
|
|
|
60
58
|
headers["Content-Transfer-Encoding"] == "binary"
|
|
61
59
|
end
|
|
62
60
|
|
|
63
|
-
def sse?(
|
|
64
|
-
|
|
61
|
+
def sse?(headers)
|
|
62
|
+
headers["Content-Type"] == "text/event-stream"
|
|
65
63
|
end
|
|
66
64
|
|
|
67
65
|
def html_request?(headers, response)
|
data/lib/bullet/version.rb
CHANGED
data/lib/bullet.rb
CHANGED
|
@@ -29,7 +29,9 @@ module Bullet
|
|
|
29
29
|
attr_reader :notification_collector, :whitelist
|
|
30
30
|
attr_accessor :add_footer, :orm_pathches_applied
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
available_notifiers = UniformNotifier::AVAILABLE_NOTIFIERS.map { |notifier| "#{notifier}=" }
|
|
33
|
+
available_notifiers << { :to => UniformNotifier }
|
|
34
|
+
delegate *available_notifiers
|
|
33
35
|
|
|
34
36
|
def raise=(should_raise)
|
|
35
37
|
UniformNotifier.raise=(should_raise ? Notification::UnoptimizedQueryError : false)
|
|
@@ -160,7 +162,7 @@ module Bullet
|
|
|
160
162
|
|
|
161
163
|
def footer_info
|
|
162
164
|
info = []
|
|
163
|
-
|
|
165
|
+
notification_collector.collection.each do |notification|
|
|
164
166
|
info << notification.short_notice
|
|
165
167
|
end
|
|
166
168
|
info
|
|
@@ -176,14 +178,17 @@ module Bullet
|
|
|
176
178
|
end
|
|
177
179
|
|
|
178
180
|
def profile
|
|
179
|
-
|
|
181
|
+
if Bullet.enable?
|
|
182
|
+
begin
|
|
183
|
+
Bullet.start_request
|
|
180
184
|
|
|
181
|
-
|
|
185
|
+
yield
|
|
182
186
|
|
|
183
|
-
|
|
184
|
-
|
|
187
|
+
Bullet.perform_out_of_channel_notifications if Bullet.notification?
|
|
188
|
+
ensure
|
|
189
|
+
Bullet.end_request
|
|
190
|
+
end
|
|
185
191
|
end
|
|
186
|
-
Bullet.end_request if Bullet.enable?
|
|
187
192
|
end
|
|
188
193
|
|
|
189
194
|
private
|
|
@@ -10,13 +10,13 @@ module Bullet
|
|
|
10
10
|
|
|
11
11
|
context ".add_counter_cache" do
|
|
12
12
|
it "should create notification if conditions met" do
|
|
13
|
-
expect(CounterCache).to receive(:conditions_met?).with(@post1
|
|
13
|
+
expect(CounterCache).to receive(:conditions_met?).with(@post1, [:comments]).and_return(true)
|
|
14
14
|
expect(CounterCache).to receive(:create_notification).with("Post", [:comments])
|
|
15
15
|
CounterCache.add_counter_cache(@post1, [:comments])
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
it "should not create notification if conditions not met" do
|
|
19
|
-
expect(CounterCache).to receive(:conditions_met?).with(@post1
|
|
19
|
+
expect(CounterCache).to receive(:conditions_met?).with(@post1, [:comments]).and_return(false)
|
|
20
20
|
expect(CounterCache).to receive(:create_notification).never
|
|
21
21
|
CounterCache.add_counter_cache(@post1, [:comments])
|
|
22
22
|
end
|
|
@@ -25,30 +25,30 @@ module Bullet
|
|
|
25
25
|
context ".add_possible_objects" do
|
|
26
26
|
it "should add possible objects" do
|
|
27
27
|
CounterCache.add_possible_objects([@post1, @post2])
|
|
28
|
-
expect(CounterCache.
|
|
29
|
-
expect(CounterCache.
|
|
28
|
+
expect(CounterCache.possible_objects).to be_include(@post1.bullet_key)
|
|
29
|
+
expect(CounterCache.possible_objects).to be_include(@post2.bullet_key)
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
it "should add impossible object" do
|
|
33
33
|
CounterCache.add_impossible_object(@post1)
|
|
34
|
-
expect(CounterCache.
|
|
34
|
+
expect(CounterCache.impossible_objects).to be_include(@post1.bullet_key)
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
context ".conditions_met?" do
|
|
39
39
|
it "should be true when object is possible, not impossible" do
|
|
40
40
|
CounterCache.add_possible_objects(@post1)
|
|
41
|
-
expect(CounterCache.
|
|
41
|
+
expect(CounterCache.conditions_met?(@post1, :associations)).to eq true
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
it "should be false when object is not possible" do
|
|
45
|
-
expect(CounterCache.
|
|
45
|
+
expect(CounterCache.conditions_met?(@post1, :associations)).to eq false
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
it "should be true when object is possible, and impossible" do
|
|
49
49
|
CounterCache.add_possible_objects(@post1)
|
|
50
50
|
CounterCache.add_impossible_object(@post1)
|
|
51
|
-
expect(CounterCache.
|
|
51
|
+
expect(CounterCache.conditions_met?(@post1, :associations)).to eq false
|
|
52
52
|
end
|
|
53
53
|
end
|
|
54
54
|
end
|
|
@@ -18,69 +18,69 @@ module Bullet
|
|
|
18
18
|
context ".possible?" do
|
|
19
19
|
it "should be true if possible_objects contain" do
|
|
20
20
|
NPlusOneQuery.add_possible_objects(@post)
|
|
21
|
-
expect(NPlusOneQuery.
|
|
21
|
+
expect(NPlusOneQuery.possible?(@post)).to eq true
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
context ".impossible?" do
|
|
26
26
|
it "should be true if impossible_objects contain" do
|
|
27
27
|
NPlusOneQuery.add_impossible_object(@post)
|
|
28
|
-
expect(NPlusOneQuery.
|
|
28
|
+
expect(NPlusOneQuery.impossible?(@post)).to eq true
|
|
29
29
|
end
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
context ".association?" do
|
|
33
33
|
it "should be true if object, associations pair is already existed" do
|
|
34
34
|
NPlusOneQuery.add_object_associations(@post, :association)
|
|
35
|
-
expect(NPlusOneQuery.
|
|
35
|
+
expect(NPlusOneQuery.association?(@post, :association)).to eq true
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
it "should be false if object, association pair is not existed" do
|
|
39
39
|
NPlusOneQuery.add_object_associations(@post, :association1)
|
|
40
|
-
expect(NPlusOneQuery.
|
|
40
|
+
expect(NPlusOneQuery.association?(@post, :associatio2)).to eq false
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
context ".conditions_met?" do
|
|
45
45
|
it "should be true if object is possible, not impossible and object, associations pair is not already existed" do
|
|
46
|
-
allow(NPlusOneQuery).to receive(:possible?).with(@post
|
|
47
|
-
allow(NPlusOneQuery).to receive(:impossible?).with(@post
|
|
48
|
-
allow(NPlusOneQuery).to receive(:association?).with(@post
|
|
49
|
-
expect(NPlusOneQuery.
|
|
46
|
+
allow(NPlusOneQuery).to receive(:possible?).with(@post).and_return(true)
|
|
47
|
+
allow(NPlusOneQuery).to receive(:impossible?).with(@post).and_return(false)
|
|
48
|
+
allow(NPlusOneQuery).to receive(:association?).with(@post, :associations).and_return(false)
|
|
49
|
+
expect(NPlusOneQuery.conditions_met?(@post, :associations)).to eq true
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
it "should be false if object is not possible, not impossible and object, associations pair is not already existed" do
|
|
53
|
-
allow(NPlusOneQuery).to receive(:possible?).with(@post
|
|
54
|
-
allow(NPlusOneQuery).to receive(:impossible?).with(@post
|
|
55
|
-
allow(NPlusOneQuery).to receive(:association?).with(@post
|
|
56
|
-
expect(NPlusOneQuery.
|
|
53
|
+
allow(NPlusOneQuery).to receive(:possible?).with(@post).and_return(false)
|
|
54
|
+
allow(NPlusOneQuery).to receive(:impossible?).with(@post).and_return(false)
|
|
55
|
+
allow(NPlusOneQuery).to receive(:association?).with(@post, :associations).and_return(false)
|
|
56
|
+
expect(NPlusOneQuery.conditions_met?(@post, :associations)).to eq false
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
it "should be false if object is possible, but impossible and object, associations pair is not already existed" do
|
|
60
|
-
allow(NPlusOneQuery).to receive(:possible?).with(@post
|
|
61
|
-
allow(NPlusOneQuery).to receive(:impossible?).with(@post
|
|
62
|
-
allow(NPlusOneQuery).to receive(:association?).with(@post
|
|
63
|
-
expect(NPlusOneQuery.
|
|
60
|
+
allow(NPlusOneQuery).to receive(:possible?).with(@post).and_return(true)
|
|
61
|
+
allow(NPlusOneQuery).to receive(:impossible?).with(@post).and_return(true)
|
|
62
|
+
allow(NPlusOneQuery).to receive(:association?).with(@post, :associations).and_return(false)
|
|
63
|
+
expect(NPlusOneQuery.conditions_met?(@post, :associations)).to eq false
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
it "should be false if object is possible, not impossible and object, associations pair is already existed" do
|
|
67
|
-
allow(NPlusOneQuery).to receive(:possible?).with(@post
|
|
68
|
-
allow(NPlusOneQuery).to receive(:impossible?).with(@post
|
|
69
|
-
allow(NPlusOneQuery).to receive(:association?).with(@post
|
|
70
|
-
expect(NPlusOneQuery.
|
|
67
|
+
allow(NPlusOneQuery).to receive(:possible?).with(@post).and_return(true)
|
|
68
|
+
allow(NPlusOneQuery).to receive(:impossible?).with(@post).and_return(false)
|
|
69
|
+
allow(NPlusOneQuery).to receive(:association?).with(@post, :associations).and_return(true)
|
|
70
|
+
expect(NPlusOneQuery.conditions_met?(@post, :associations)).to eq false
|
|
71
71
|
end
|
|
72
72
|
end
|
|
73
73
|
|
|
74
74
|
context ".call_association" do
|
|
75
75
|
it "should create notification if conditions met" do
|
|
76
|
-
expect(NPlusOneQuery).to receive(:conditions_met?).with(@post
|
|
76
|
+
expect(NPlusOneQuery).to receive(:conditions_met?).with(@post, :association).and_return(true)
|
|
77
77
|
expect(NPlusOneQuery).to receive(:caller_in_project).and_return(["caller"])
|
|
78
78
|
expect(NPlusOneQuery).to receive(:create_notification).with(["caller"], "Post", :association)
|
|
79
79
|
NPlusOneQuery.call_association(@post, :association)
|
|
80
80
|
end
|
|
81
81
|
|
|
82
82
|
it "should not create notification if conditions not met" do
|
|
83
|
-
expect(NPlusOneQuery).to receive(:conditions_met?).with(@post
|
|
83
|
+
expect(NPlusOneQuery).to receive(:conditions_met?).with(@post, :association).and_return(false)
|
|
84
84
|
expect(NPlusOneQuery).not_to receive(:caller_in_project!)
|
|
85
85
|
expect(NPlusOneQuery).not_to receive(:create_notification).with("Post", :association)
|
|
86
86
|
NPlusOneQuery.call_association(@post, :association)
|
|
@@ -93,7 +93,7 @@ module Bullet
|
|
|
93
93
|
not_in_project = '/def/def.rb'
|
|
94
94
|
|
|
95
95
|
expect(NPlusOneQuery).to receive(:caller).and_return([in_project, not_in_project])
|
|
96
|
-
expect(NPlusOneQuery).to receive(:conditions_met?).with(@post
|
|
96
|
+
expect(NPlusOneQuery).to receive(:conditions_met?).with(@post, :association).and_return(true)
|
|
97
97
|
expect(NPlusOneQuery).to receive(:create_notification).with([in_project], "Post", :association)
|
|
98
98
|
NPlusOneQuery.call_association(@post, :association)
|
|
99
99
|
end
|
|
@@ -108,7 +108,7 @@ module Bullet
|
|
|
108
108
|
excluded_gem = '/ghi/ghi.rb'
|
|
109
109
|
|
|
110
110
|
expect(NPlusOneQuery).to receive(:caller).and_return([in_project, included_gem, excluded_gem])
|
|
111
|
-
expect(NPlusOneQuery).to receive(:conditions_met?).with(@post
|
|
111
|
+
expect(NPlusOneQuery).to receive(:conditions_met?).with(@post, :association).and_return(true)
|
|
112
112
|
expect(NPlusOneQuery).to receive(:create_notification).with([in_project, included_gem], "Post", :association)
|
|
113
113
|
NPlusOneQuery.call_association(@post, :association)
|
|
114
114
|
end
|
|
@@ -118,8 +118,8 @@ module Bullet
|
|
|
118
118
|
context ".add_possible_objects" do
|
|
119
119
|
it "should add possible objects" do
|
|
120
120
|
NPlusOneQuery.add_possible_objects([@post, @post2])
|
|
121
|
-
expect(NPlusOneQuery.
|
|
122
|
-
expect(NPlusOneQuery.
|
|
121
|
+
expect(NPlusOneQuery.possible_objects).to be_include(@post.bullet_key)
|
|
122
|
+
expect(NPlusOneQuery.possible_objects).to be_include(@post2.bullet_key)
|
|
123
123
|
end
|
|
124
124
|
|
|
125
125
|
it "should not raise error if object is nil" do
|
|
@@ -130,7 +130,7 @@ module Bullet
|
|
|
130
130
|
context ".add_impossible_object" do
|
|
131
131
|
it "should add impossible object" do
|
|
132
132
|
NPlusOneQuery.add_impossible_object(@post)
|
|
133
|
-
expect(NPlusOneQuery.
|
|
133
|
+
expect(NPlusOneQuery.impossible_objects).to be_include(@post.bullet_key)
|
|
134
134
|
end
|
|
135
135
|
end
|
|
136
136
|
end
|
data/spec/bullet/rack_spec.rb
CHANGED
|
@@ -65,7 +65,7 @@ module Bullet
|
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
it "should change response body if notification is active" do
|
|
68
|
-
expect(Bullet).to receive(:notification?).and_return(true)
|
|
68
|
+
expect(Bullet).to receive(:notification?).and_return(true)
|
|
69
69
|
expect(Bullet).to receive(:gather_inline_notifications).and_return("<bullet></bullet>")
|
|
70
70
|
expect(Bullet).to receive(:perform_out_of_channel_notifications)
|
|
71
71
|
status, headers, response = middleware.call([200, {"Content-Type" => "text/html"}])
|
|
@@ -77,7 +77,7 @@ module Bullet
|
|
|
77
77
|
response = Support::ResponseDouble.new
|
|
78
78
|
response.body = "<html><head></head><body>é</body></html>"
|
|
79
79
|
app.response = response
|
|
80
|
-
expect(Bullet).to receive(:notification?).and_return(true)
|
|
80
|
+
expect(Bullet).to receive(:notification?).and_return(true)
|
|
81
81
|
expect(Bullet).to receive(:gather_inline_notifications).and_return("<bullet></bullet>")
|
|
82
82
|
status, headers, response = middleware.call([200, {"Content-Type" => "text/html"}])
|
|
83
83
|
expect(headers["Content-Length"]).to eq("58")
|
|
@@ -335,6 +335,15 @@ if !mongoid? && active_record3?
|
|
|
335
335
|
expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Comment, :post)
|
|
336
336
|
end
|
|
337
337
|
|
|
338
|
+
it "should not detect non preload association with only one comment" do
|
|
339
|
+
Comment.first.post.category.name
|
|
340
|
+
|
|
341
|
+
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
|
342
|
+
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
|
343
|
+
|
|
344
|
+
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
|
345
|
+
end
|
|
346
|
+
|
|
338
347
|
it "should detect non preload association with post => category" do
|
|
339
348
|
Comment.includes(:post).each do |comment|
|
|
340
349
|
comment.post.category.name
|
|
@@ -347,6 +347,15 @@ if !mongoid? && active_record4?
|
|
|
347
347
|
expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Comment, :post)
|
|
348
348
|
end
|
|
349
349
|
|
|
350
|
+
it "should not detect non preload association with only one comment" do
|
|
351
|
+
Comment.first.post.category.name
|
|
352
|
+
|
|
353
|
+
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
|
354
|
+
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
|
355
|
+
|
|
356
|
+
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
|
357
|
+
end
|
|
358
|
+
|
|
350
359
|
it "should detect non preload association with post => category" do
|
|
351
360
|
Comment.includes(:post).each do |comment|
|
|
352
361
|
comment.post.category.name
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: bullet
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.14.
|
|
4
|
+
version: 4.14.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Richard Huang
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2015-
|
|
11
|
+
date: 2015-05-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -28,16 +28,16 @@ dependencies:
|
|
|
28
28
|
name: uniform_notifier
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
|
-
- - "
|
|
31
|
+
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: 1.
|
|
33
|
+
version: 1.9.0
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
|
-
- - "
|
|
38
|
+
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: 1.
|
|
40
|
+
version: 1.9.0
|
|
41
41
|
description: help to kill N+1 queries and unused eager loading.
|
|
42
42
|
email:
|
|
43
43
|
- flyerhzm@gmail.com
|
|
@@ -184,7 +184,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
184
184
|
version: 1.3.6
|
|
185
185
|
requirements: []
|
|
186
186
|
rubyforge_project:
|
|
187
|
-
rubygems_version: 2.4.
|
|
187
|
+
rubygems_version: 2.4.6
|
|
188
188
|
signing_key:
|
|
189
189
|
specification_version: 4
|
|
190
190
|
summary: help to kill N+1 queries and unused eager loading.
|