bullet 4.11.3 → 4.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -3
- data/Gemfile.mongoid-4.0 +1 -1
- data/Gemfile.rails-3.2 +1 -1
- data/Gemfile.rails-4.0 +1 -1
- data/Gemfile.rails-4.1 +1 -1
- data/README.md +44 -40
- data/lib/bullet.rb +4 -2
- data/lib/bullet/active_record3.rb +1 -1
- data/lib/bullet/active_record3x.rb +1 -1
- data/lib/bullet/active_record4.rb +1 -11
- data/lib/bullet/active_record41.rb +1 -0
- data/lib/bullet/detector/association.rb +9 -3
- data/lib/bullet/detector/counter_cache.rb +3 -3
- data/lib/bullet/detector/n_plus_one_query.rb +13 -3
- data/lib/bullet/detector/unused_eager_loading.rb +1 -1
- data/lib/bullet/ext/object.rb +6 -2
- data/lib/bullet/version.rb +1 -1
- data/spec/bullet/ext/object_spec.rb +14 -0
- data/spec/integration/active_record3/association_spec.rb +1 -1
- data/spec/models/category.rb +1 -1
- data/spec/models/post.rb +1 -1
- data/spec/spec_helper.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b201e99b1db5ea0ae016eb415b8bdcb2141a0321
|
4
|
+
data.tar.gz: 072c423687b8482273549f30c2538edec5c3c03f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 624bfcc8a8f2044699d19e598729cba0bf858e054002b435a31cce643d1bc3834139dad14ea510ef573a31059ce13f4b5c1dd892404645cca8d77e47264db794
|
7
|
+
data.tar.gz: ffaf8125f6797fd85b42be44f645e835796d623bc8b656662b8bd7387ac3b92882d4f2daaf2c50c04aced38113d7c96fbd8b3bdf631bd532c0a02663e221e1d1
|
data/CHANGELOG.md
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
# Next Release
|
2
2
|
|
3
|
-
## 4.12.0
|
3
|
+
## 4.12.0
|
4
4
|
|
5
|
-
*
|
5
|
+
* Fix false n+1 queries caused by inversed objects.
|
6
|
+
* Replace .id with .primary_key_value
|
6
7
|
* Rename bullet_ar_key to bullet_key
|
7
8
|
* Fix rails sse detect
|
8
|
-
* Fix bullet in
|
9
|
+
* Fix bullet using in test environment
|
9
10
|
* Memoize whoami
|
10
11
|
|
11
12
|
## 4.11.0 (06/24/2014)
|
data/Gemfile.mongoid-4.0
CHANGED
data/Gemfile.rails-3.2
CHANGED
data/Gemfile.rails-4.0
CHANGED
data/Gemfile.rails-4.1
CHANGED
data/README.md
CHANGED
@@ -60,7 +60,7 @@ config.after_initialize do
|
|
60
60
|
end
|
61
61
|
```
|
62
62
|
|
63
|
-
The notifier of
|
63
|
+
The notifier of Bullet is a wrap of [uniform_notifier](https://github.com/flyerhzm/uniform_notifier)
|
64
64
|
|
65
65
|
The code above will enable all seven of the Bullet notification systems:
|
66
66
|
* `Bullet.enable`: enable Bullet gem, otherwise do nothing
|
@@ -70,25 +70,31 @@ The code above will enable all seven of the Bullet notification systems:
|
|
70
70
|
* `Bullet.airbrake`: add notifications to airbrake
|
71
71
|
* `Bullet.console`: log warnings to your browser's console.log (Safari/Webkit browsers or Firefox w/Firebug installed)
|
72
72
|
* `Bullet.growl`: pop up Growl warnings if your system has Growl installed. Requires a little bit of configuration
|
73
|
-
* `Bullet.xmpp`: send XMPP/Jabber notifications to the receiver indicated. Note that the code will currently not handle the adding of contacts, so you will need to make both accounts indicated know each other manually before you will receive any notifications. If you restart the development server frequently, the 'coming online' sound for the
|
73
|
+
* `Bullet.xmpp`: send XMPP/Jabber notifications to the receiver indicated. Note that the code will currently not handle the adding of contacts, so you will need to make both accounts indicated know each other manually before you will receive any notifications. If you restart the development server frequently, the 'coming online' sound for the Bullet account may start to annoy - in this case set :show_online_status to false; you will still get notifications, but the Bullet account won't announce it's online status anymore.
|
74
74
|
* `Bullet.raise`: raise errors, useful for making your specs fail unless they have optimized queries
|
75
75
|
* `Bullet.add_footer`: adds the details in the bottom left corner of the page
|
76
76
|
* `Bullet.stacktrace_includes`: include paths with any of these substrings in the stack trace, even if they are not in your main app
|
77
77
|
|
78
|
-
Bullet also allows you to disable
|
79
|
-
and counter_cache detectors respectively.
|
78
|
+
Bullet also allows you to disable any of its detectors.
|
80
79
|
|
81
80
|
```ruby
|
82
|
-
|
81
|
+
# Each of these settings defaults to true
|
82
|
+
|
83
|
+
# Detect N+1 queries
|
84
|
+
Bullet.n_plus_one_query_enable = false
|
85
|
+
|
86
|
+
# Detect eager-loaded associations which are not used
|
83
87
|
Bullet.unused_eager_loading_enable = false
|
84
|
-
|
88
|
+
|
89
|
+
# Detect unnecessary COUNT queries which could be avoided
|
90
|
+
# with a counter_cache
|
91
|
+
Bullet.counter_cache_enable = false
|
85
92
|
```
|
86
93
|
|
87
94
|
## Whitelist
|
88
95
|
|
89
|
-
Sometimes
|
90
|
-
|
91
|
-
that you can't fix, you can add whitelist to bullet
|
96
|
+
Sometimes Bullet may notify you of query problems you don't care to fix, or
|
97
|
+
which come from outside your code. You can whitelist these to ignore them:
|
92
98
|
|
93
99
|
```ruby
|
94
100
|
Bullet.add_whitelist :type => :n_plus_one_query, :class_name => "Post", :association => :comments
|
@@ -136,13 +142,13 @@ see [https://github.com/flyerhzm/uniform_notifier](https://github.com/flyerhzm/u
|
|
136
142
|
|
137
143
|
## Important
|
138
144
|
|
139
|
-
If you find
|
145
|
+
If you find Bullet does not work for you, *please disable your browser's cache*.
|
140
146
|
|
141
147
|
## Advanced
|
142
148
|
|
143
149
|
### Profile a job
|
144
150
|
|
145
|
-
The
|
151
|
+
The Bullet gem uses rack middleware to profile requests. If you want to use Bullet without an http server, like to profile a job, you can use use profile method and fetch warnings
|
146
152
|
|
147
153
|
```ruby
|
148
154
|
Bullet.profile do
|
@@ -153,7 +159,7 @@ warnings = Bullet.warnings
|
|
153
159
|
|
154
160
|
### Work with sinatra
|
155
161
|
|
156
|
-
Configure and use
|
162
|
+
Configure and use `Bullet::Rack`
|
157
163
|
|
158
164
|
```ruby
|
159
165
|
configure :development do
|
@@ -165,7 +171,7 @@ end
|
|
165
171
|
|
166
172
|
### Run in tests
|
167
173
|
|
168
|
-
First you need to enable
|
174
|
+
First you need to enable Bullet in test environment.
|
169
175
|
|
170
176
|
```ruby
|
171
177
|
# config/environments/test.rb
|
@@ -176,7 +182,7 @@ config.after_initialize do
|
|
176
182
|
end
|
177
183
|
```
|
178
184
|
|
179
|
-
Then wrap each test in
|
185
|
+
Then wrap each test in Bullet api.
|
180
186
|
|
181
187
|
```ruby
|
182
188
|
# spec/spec_helper.rb
|
@@ -194,18 +200,18 @@ end
|
|
194
200
|
|
195
201
|
## Debug Mode
|
196
202
|
|
197
|
-
Bullet outputs some details info, to enable debug mode, set
|
198
|
-
env.
|
203
|
+
Bullet outputs some details info, to enable debug mode, set
|
204
|
+
`BULLET_DEBUG=true` env.
|
199
205
|
|
200
206
|
## Contributors
|
201
207
|
|
202
208
|
[https://github.com/flyerhzm/bullet/contributors](https://github.com/flyerhzm/bullet/contributors)
|
203
209
|
|
204
|
-
##
|
210
|
+
## Demo
|
205
211
|
|
206
|
-
Bullet is designed to function as you browse through your application in development.
|
212
|
+
Bullet is designed to function as you browse through your application in development. To see it in action, follow these steps to create, detect, and fix example query problems.
|
207
213
|
|
208
|
-
1\.
|
214
|
+
1\. Create an example application
|
209
215
|
|
210
216
|
```
|
211
217
|
$ rails new test_bullet
|
@@ -215,7 +221,7 @@ $ rails g scaffold comment name:string post_id:integer
|
|
215
221
|
$ bundle exec rake db:migrate
|
216
222
|
```
|
217
223
|
|
218
|
-
2\.
|
224
|
+
2\. Change `app/model/post.rb` and `app/model/comment.rb`
|
219
225
|
|
220
226
|
```ruby
|
221
227
|
class Post < ActiveRecord::Base
|
@@ -227,7 +233,7 @@ class Comment < ActiveRecord::Base
|
|
227
233
|
end
|
228
234
|
```
|
229
235
|
|
230
|
-
3\.
|
236
|
+
3\. Go to `rails c` and execute
|
231
237
|
|
232
238
|
```ruby
|
233
239
|
post1 = Post.create(:name => 'first')
|
@@ -238,7 +244,7 @@ post2.comments.create(:name => 'third')
|
|
238
244
|
post2.comments.create(:name => 'fourth')
|
239
245
|
```
|
240
246
|
|
241
|
-
4\.
|
247
|
+
4\. Change the `app/views/posts/index.html.erb` to produce a N+1 query
|
242
248
|
|
243
249
|
```
|
244
250
|
<% @posts.each do |post| %>
|
@@ -252,7 +258,7 @@ post2.comments.create(:name => 'fourth')
|
|
252
258
|
<% end %>
|
253
259
|
```
|
254
260
|
|
255
|
-
5\.
|
261
|
+
5\. Add the `bullet` gem to the `Gemfile`
|
256
262
|
|
257
263
|
```ruby
|
258
264
|
gem "bullet"
|
@@ -264,7 +270,7 @@ And run
|
|
264
270
|
bundle install
|
265
271
|
```
|
266
272
|
|
267
|
-
6\. enable the
|
273
|
+
6\. enable the Bullet gem in development, add a line to
|
268
274
|
`config/environments/development.rb`
|
269
275
|
|
270
276
|
```ruby
|
@@ -279,13 +285,13 @@ config.after_initialize do
|
|
279
285
|
end
|
280
286
|
```
|
281
287
|
|
282
|
-
7\.
|
288
|
+
7\. Start the server
|
283
289
|
|
284
290
|
```
|
285
291
|
$ rails s
|
286
292
|
```
|
287
293
|
|
288
|
-
8\.
|
294
|
+
8\. Visit `http://localhost:3000/posts` in browser, and you will see a popup alert box that says
|
289
295
|
|
290
296
|
```
|
291
297
|
The request has unused preload associations as follows:
|
@@ -294,7 +300,7 @@ The request has N+1 queries as follows:
|
|
294
300
|
model: Post => associations: [comment]
|
295
301
|
```
|
296
302
|
|
297
|
-
which means there is a N+1 query from
|
303
|
+
which means there is a N+1 query from the Post object to its Comment association.
|
298
304
|
|
299
305
|
In the meanwhile, there's a log appended into `log/bullet.log` file
|
300
306
|
|
@@ -309,7 +315,7 @@ In the meanwhile, there's a log appended into `log/bullet.log` file
|
|
309
315
|
/home/flyerhzm/Downloads/test_bullet/app/controllers/posts_controller.rb:7:in `index'
|
310
316
|
```
|
311
317
|
|
312
|
-
The generated
|
318
|
+
The generated SQL is:
|
313
319
|
|
314
320
|
```
|
315
321
|
Post Load (1.0ms) SELECT * FROM "posts"
|
@@ -317,8 +323,7 @@ Comment Load (0.4ms) SELECT * FROM "comments" WHERE ("comments".post_id = 1)
|
|
317
323
|
Comment Load (0.3ms) SELECT * FROM "comments" WHERE ("comments".post_id = 2)
|
318
324
|
```
|
319
325
|
|
320
|
-
|
321
|
-
9\. fix the N+1 query, change `app/controllers/posts_controller.rb` file
|
326
|
+
9\. To fix the N+1 query, change `app/controllers/posts_controller.rb` file
|
322
327
|
|
323
328
|
```ruby
|
324
329
|
def index
|
@@ -331,18 +336,18 @@ def index
|
|
331
336
|
end
|
332
337
|
```
|
333
338
|
|
334
|
-
10\.
|
339
|
+
10\. Refresh `http://localhost:3000/posts`. Now there's no alert box and nothing new in the log.
|
335
340
|
|
336
|
-
The generated
|
341
|
+
The generated SQL is:
|
337
342
|
|
338
343
|
```
|
339
344
|
Post Load (0.5ms) SELECT * FROM "posts"
|
340
345
|
Comment Load (0.5ms) SELECT "comments".* FROM "comments" WHERE ("comments".post_id IN (1,2))
|
341
346
|
```
|
342
347
|
|
343
|
-
|
348
|
+
N+1 query fixed. Cool!
|
344
349
|
|
345
|
-
11\.
|
350
|
+
11\. Now simulate unused eager loading. Change
|
346
351
|
`app/controllers/posts_controller.rb` and
|
347
352
|
`app/views/posts/index.html.erb`
|
348
353
|
|
@@ -368,7 +373,7 @@ end
|
|
368
373
|
<% end %>
|
369
374
|
```
|
370
375
|
|
371
|
-
12\.
|
376
|
+
12\. Refresh `http://localhost:3000/posts`, and you will see a popup alert box that says
|
372
377
|
|
373
378
|
```
|
374
379
|
The request has unused preload associations as follows:
|
@@ -377,14 +382,14 @@ The request has N+1 queries as follows:
|
|
377
382
|
None
|
378
383
|
```
|
379
384
|
|
380
|
-
|
385
|
+
Meanwhile, there's a line appended to `log/bullet.log`
|
381
386
|
|
382
387
|
```
|
383
388
|
2009-08-25 21:13:22[INFO] Unused preload associations: PATH_INFO: /posts; model: Post => associations: [comments]·
|
384
389
|
Remove from your finder: :include => [:comments]
|
385
390
|
```
|
386
391
|
|
387
|
-
13\.
|
392
|
+
13\. Simulate counter_cache. Change `app/controllers/posts_controller.rb`
|
388
393
|
and `app/views/posts/index.html.erb`
|
389
394
|
|
390
395
|
```ruby
|
@@ -410,19 +415,18 @@ end
|
|
410
415
|
<% end %>
|
411
416
|
```
|
412
417
|
|
413
|
-
14\.
|
418
|
+
14\. Refresh `http://localhost:3000/posts`, then you will see a popup alert box that says
|
414
419
|
|
415
420
|
```
|
416
421
|
Need counter cache
|
417
422
|
Post => [:comments]
|
418
423
|
```
|
419
424
|
|
420
|
-
|
425
|
+
Meanwhile, there's a line appended to `log/bullet.log`
|
421
426
|
|
422
427
|
```
|
423
428
|
2009-09-11 10:07:10[INFO] Need Counter Cache
|
424
429
|
Post => [:comments]
|
425
430
|
```
|
426
431
|
|
427
|
-
|
428
432
|
Copyright (c) 2009 - 2014 Richard Huang (flyerhzm@gmail.com), released under the MIT license
|
data/lib/bullet.rb
CHANGED
@@ -96,7 +96,7 @@ module Bullet
|
|
96
96
|
end
|
97
97
|
|
98
98
|
def debug(title, message)
|
99
|
-
puts "[Bullet][#{title}] #{message}" if ENV['
|
99
|
+
puts "[Bullet][#{title}] #{message}" if ENV['BULLET_DEBUG'] == 'true'
|
100
100
|
end
|
101
101
|
|
102
102
|
def start_request
|
@@ -107,6 +107,7 @@ module Bullet
|
|
107
107
|
Thread.current[:bullet_call_object_associations] = Bullet::Registry::Base.new
|
108
108
|
Thread.current[:bullet_possible_objects] = Bullet::Registry::Object.new
|
109
109
|
Thread.current[:bullet_impossible_objects] = Bullet::Registry::Object.new
|
110
|
+
Thread.current[:bullet_inversed_objects] = Bullet::Registry::Base.new
|
110
111
|
Thread.current[:bullet_eager_loadings] = Bullet::Registry::Association.new
|
111
112
|
|
112
113
|
Thread.current[:bullet_counter_possible_objects] ||= Bullet::Registry::Object.new
|
@@ -118,9 +119,10 @@ module Bullet
|
|
118
119
|
Thread.current[:bullet_notification_collector] = nil
|
119
120
|
|
120
121
|
Thread.current[:bullet_object_associations] = nil
|
122
|
+
Thread.current[:bullet_call_object_associations] = nil
|
121
123
|
Thread.current[:bullet_possible_objects] = nil
|
122
124
|
Thread.current[:bullet_impossible_objects] = nil
|
123
|
-
Thread.current[:
|
125
|
+
Thread.current[:bullet_inversed_objects] = nil
|
124
126
|
Thread.current[:bullet_eager_loadings] = nil
|
125
127
|
|
126
128
|
Thread.current[:bullet_counter_possible_objects] = nil
|
@@ -119,7 +119,7 @@ module Bullet
|
|
119
119
|
alias_method :origin_set_inverse_instance, :set_inverse_instance
|
120
120
|
def set_inverse_instance(record, instance)
|
121
121
|
if record && we_can_set_the_inverse_on_this?(record)
|
122
|
-
Bullet::Detector::NPlusOneQuery.
|
122
|
+
Bullet::Detector::NPlusOneQuery.add_inversed_object(record, @reflection.inverse_of.name)
|
123
123
|
end
|
124
124
|
origin_set_inverse_instance(record, instance)
|
125
125
|
end
|
@@ -108,7 +108,7 @@ module Bullet
|
|
108
108
|
alias_method :origin_set_inverse_instance, :set_inverse_instance
|
109
109
|
def set_inverse_instance(record)
|
110
110
|
if record && invertible_for?(record)
|
111
|
-
Bullet::Detector::NPlusOneQuery.
|
111
|
+
Bullet::Detector::NPlusOneQuery.add_inversed_object(record, inverse_reflection_for(record).name)
|
112
112
|
end
|
113
113
|
origin_set_inverse_instance(record)
|
114
114
|
end
|
@@ -98,22 +98,12 @@ module Bullet
|
|
98
98
|
alias_method :origin_reader, :reader
|
99
99
|
def reader(force_reload = false)
|
100
100
|
result = origin_reader(force_reload)
|
101
|
-
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
101
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name) unless @inversed
|
102
102
|
Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
|
103
103
|
result
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
107
|
-
::ActiveRecord::Associations::Association.class_eval do
|
108
|
-
alias_method :origin_set_inverse_instance, :set_inverse_instance
|
109
|
-
def set_inverse_instance(record)
|
110
|
-
if record && invertible_for?(record)
|
111
|
-
Bullet::Detector::NPlusOneQuery.add_impossible_object(record)
|
112
|
-
end
|
113
|
-
origin_set_inverse_instance(record)
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
107
|
::ActiveRecord::Associations::HasManyAssociation.class_eval do
|
118
108
|
alias_method :origin_has_cached_counter?, :has_cached_counter?
|
119
109
|
|
@@ -27,6 +27,7 @@ module Bullet
|
|
27
27
|
def preloaders_on(association, records, scope)
|
28
28
|
if records.first.class.name !~ /^HABTM_/
|
29
29
|
records.each do |record|
|
30
|
+
next unless record
|
30
31
|
Bullet::Detector::Association.add_object_associations(record, association)
|
31
32
|
end
|
32
33
|
Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, association)
|
@@ -5,7 +5,7 @@ module Bullet
|
|
5
5
|
def add_object_associations(object, associations)
|
6
6
|
return unless Bullet.start?
|
7
7
|
return if !Bullet.n_plus_one_query_enable? && !Bullet.unused_eager_loading_enable?
|
8
|
-
return unless object.
|
8
|
+
return unless object.primary_key_value
|
9
9
|
|
10
10
|
Bullet.debug("Detector::Association#add_object_associations", "object: #{object.bullet_key}, associations: #{associations}")
|
11
11
|
object_associations.add(object.bullet_key, associations)
|
@@ -14,7 +14,7 @@ module Bullet
|
|
14
14
|
def add_call_object_associations(object, associations)
|
15
15
|
return unless Bullet.start?
|
16
16
|
return if !Bullet.n_plus_one_query_enable? && !Bullet.unused_eager_loading_enable?
|
17
|
-
return unless object.
|
17
|
+
return unless object.primary_key_value
|
18
18
|
|
19
19
|
Bullet.debug("Detector::Association#add_call_object_associations", "object: #{object.bullet_key}, associations: #{associations}")
|
20
20
|
call_object_associations.add(object.bullet_key, associations)
|
@@ -48,13 +48,19 @@ module Bullet
|
|
48
48
|
# impossible_objects keep the class to objects relationships
|
49
49
|
# that the objects may not cause N+1 query.
|
50
50
|
# e.g. { Post => ["Post:1", "Post:2"] }
|
51
|
-
# Notice: impossible_objects are not accurate,
|
52
51
|
# if find collection returns only one object, then the object is impossible object,
|
53
52
|
# impossible_objects are used to avoid treating 1+1 query to N+1 query.
|
54
53
|
def impossible_objects
|
55
54
|
Thread.current[:bullet_impossible_objects]
|
56
55
|
end
|
57
56
|
|
57
|
+
# inversed_objects keeps object relationships
|
58
|
+
# that association is inversed.
|
59
|
+
# e.g. { "Comment:1" => ["post"] }
|
60
|
+
def inversed_objects
|
61
|
+
Thread.current[:bullet_inversed_objects]
|
62
|
+
end
|
63
|
+
|
58
64
|
# eager_loadings keep the object relationships
|
59
65
|
# that the associations are preloaded by find :include.
|
60
66
|
# e.g. { ["Post:1", "Post:2"] => [:comments, :user] }
|
@@ -5,7 +5,7 @@ module Bullet
|
|
5
5
|
def add_counter_cache(object, associations)
|
6
6
|
return unless Bullet.start?
|
7
7
|
return unless Bullet.counter_cache_enable?
|
8
|
-
return unless object.
|
8
|
+
return unless object.primary_key_value
|
9
9
|
|
10
10
|
Bullet.debug("Detector::CounterCache#add_counter_cache", "object: #{object.bullet_key}, associations: #{associations}")
|
11
11
|
if conditions_met?(object.bullet_key, associations)
|
@@ -17,7 +17,7 @@ module Bullet
|
|
17
17
|
return unless Bullet.start?
|
18
18
|
return unless Bullet.counter_cache_enable?
|
19
19
|
objects = Array(object_or_objects)
|
20
|
-
return if objects.map(&:
|
20
|
+
return if objects.map(&:primary_key_value).compact.empty?
|
21
21
|
|
22
22
|
Bullet.debug("Detector::CounterCache#add_possible_objects", "objects: #{objects.map(&:bullet_key).join(', ')}")
|
23
23
|
objects.each { |object| possible_objects.add object.bullet_key }
|
@@ -26,7 +26,7 @@ module Bullet
|
|
26
26
|
def add_impossible_object(object)
|
27
27
|
return unless Bullet.start?
|
28
28
|
return unless Bullet.counter_cache_enable?
|
29
|
-
return unless object.
|
29
|
+
return unless object.primary_key_value
|
30
30
|
|
31
31
|
Bullet.debug("Detector::CounterCache#add_impossible_object", "object: #{object.bullet_key}")
|
32
32
|
impossible_objects.add object.bullet_key
|
@@ -10,7 +10,8 @@ module Bullet
|
|
10
10
|
# if it is, keeps this unpreload associations and caller.
|
11
11
|
def call_association(object, associations)
|
12
12
|
return unless Bullet.start?
|
13
|
-
return unless object.
|
13
|
+
return unless object.primary_key_value
|
14
|
+
return if inversed_objects.include?(object.bullet_key, associations)
|
14
15
|
add_call_object_associations(object, associations)
|
15
16
|
|
16
17
|
Bullet.debug("Detector::NPlusOneQuery#call_association", "object: #{object.bullet_key}, associations: #{associations}")
|
@@ -24,7 +25,7 @@ module Bullet
|
|
24
25
|
return unless Bullet.start?
|
25
26
|
return unless Bullet.n_plus_one_query_enable?
|
26
27
|
objects = Array(object_or_objects)
|
27
|
-
return if objects.map(&:
|
28
|
+
return if objects.map(&:primary_key_value).compact.empty?
|
28
29
|
|
29
30
|
Bullet.debug("Detector::NPlusOneQuery#add_possible_objects", "objects: #{objects.map(&:bullet_key).join(', ')}")
|
30
31
|
objects.each { |object| possible_objects.add object.bullet_key }
|
@@ -33,12 +34,21 @@ module Bullet
|
|
33
34
|
def add_impossible_object(object)
|
34
35
|
return unless Bullet.start?
|
35
36
|
return unless Bullet.n_plus_one_query_enable?
|
36
|
-
return unless object.
|
37
|
+
return unless object.primary_key_value
|
37
38
|
|
38
39
|
Bullet.debug("Detector::NPlusOneQuery#add_impossible_object", "object: #{object.bullet_key}")
|
39
40
|
impossible_objects.add object.bullet_key
|
40
41
|
end
|
41
42
|
|
43
|
+
def add_inversed_object(object, association)
|
44
|
+
return unless Bullet.start?
|
45
|
+
return unless Bullet.n_plus_one_query_enable?
|
46
|
+
return unless object.primary_key_value
|
47
|
+
|
48
|
+
Bullet.debug("Detector::NPlusOneQuery#add_inversed_object", "object: #{object.bullet_key}, association: #{association}")
|
49
|
+
inversed_objects.add object.bullet_key, association
|
50
|
+
end
|
51
|
+
|
42
52
|
private
|
43
53
|
def create_notification(callers, klazz, associations)
|
44
54
|
notify_associations = Array(associations) - Bullet.get_whitelist_associations(:n_plus_one_query, klazz)
|
@@ -22,7 +22,7 @@ module Bullet
|
|
22
22
|
def add_eager_loadings(objects, associations)
|
23
23
|
return unless Bullet.start?
|
24
24
|
return unless Bullet.unused_eager_loading_enable?
|
25
|
-
return if objects.map(&:
|
25
|
+
return if objects.map(&:primary_key_value).compact.empty?
|
26
26
|
|
27
27
|
Bullet.debug("Detector::UnusedEagerLoading#add_eager_loadings", "objects: #{objects.map(&:bullet_key).join(', ')}, associations: #{associations}")
|
28
28
|
bullet_keys = objects.map(&:bullet_key)
|
data/lib/bullet/ext/object.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
class Object
|
2
2
|
def bullet_key
|
3
|
+
[self.class, self.primary_key_value].join(':')
|
4
|
+
end
|
5
|
+
|
6
|
+
def primary_key_value
|
3
7
|
if self.class.respond_to?(:primary_key) && self.class.primary_key
|
4
|
-
|
8
|
+
self.send self.class.primary_key
|
5
9
|
else
|
6
|
-
|
10
|
+
self.id
|
7
11
|
end
|
8
12
|
end
|
9
13
|
end
|
data/lib/bullet/version.rb
CHANGED
@@ -14,4 +14,18 @@ describe Object do
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
17
|
+
|
18
|
+
context "primary_key_value" do
|
19
|
+
it "should return id" do
|
20
|
+
post = Post.first
|
21
|
+
expect(post.primary_key_value).to eq(post.id)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should return primary key value" do
|
25
|
+
post = Post.first
|
26
|
+
Post.primary_key = 'name'
|
27
|
+
expect(post.primary_key_value).to eq(post.name)
|
28
|
+
Post.primary_key = 'id'
|
29
|
+
end
|
30
|
+
end
|
17
31
|
end
|
@@ -39,7 +39,7 @@ if !mongoid? && active_record3?
|
|
39
39
|
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
40
40
|
end
|
41
41
|
|
42
|
-
it "should detect non preload comment => post with inverse_of" do
|
42
|
+
it "should not detect non preload comment => post with inverse_of" do
|
43
43
|
Post.includes(:comments).each do |post|
|
44
44
|
post.comments.each do |comment|
|
45
45
|
comment.name
|
data/spec/models/category.rb
CHANGED
data/spec/models/post.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -65,7 +65,7 @@ if active_record?
|
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
|
-
if ENV["
|
68
|
+
if ENV["BULLET_LOG"]
|
69
69
|
require 'logger'
|
70
70
|
ActiveRecord::Base.logger = Logger.new(STDOUT)
|
71
71
|
end
|
@@ -96,7 +96,7 @@ if mongoid?
|
|
96
96
|
end
|
97
97
|
end
|
98
98
|
|
99
|
-
if ENV["
|
99
|
+
if ENV["BULLET_LOG"]
|
100
100
|
Mongoid.logger = Logger.new(STDOUT)
|
101
101
|
Moped.logger = Logger.new(STDOUT)
|
102
102
|
end
|
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.
|
4
|
+
version: 4.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Richard Huang
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-07-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|