bullet 4.4.0 → 4.5.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 +31 -0
- data/{Hacking.textile → Hacking.md} +10 -5
- data/{README.textile → README.md} +174 -144
- data/lib/bullet.rb +42 -7
- data/lib/bullet/active_record2.rb +9 -9
- data/lib/bullet/active_record3.rb +9 -9
- data/lib/bullet/active_record3x.rb +8 -8
- data/lib/bullet/active_record4.rb +8 -8
- data/lib/bullet/detector.rb +2 -2
- data/lib/bullet/detector/association.rb +2 -43
- data/lib/bullet/detector/{counter.rb → counter_cache.rb} +13 -3
- data/lib/bullet/detector/n_plus_one_query.rb +21 -2
- data/lib/bullet/detector/{unused_eager_association.rb → unused_eager_loading.rb} +40 -3
- data/lib/bullet/mongoid2x.rb +5 -5
- data/lib/bullet/mongoid3x.rb +6 -6
- data/lib/bullet/version.rb +1 -1
- data/spec/bullet/detector/association_spec.rb +0 -49
- data/spec/bullet/detector/counter_cache_spec.rb +64 -0
- data/spec/bullet/detector/n_plus_one_query_spec.rb +23 -1
- data/spec/bullet/detector/unused_eager_loading_spec.rb +95 -0
- data/spec/integration/association_spec.rb +141 -49
- data/spec/integration/{counter_spec.rb → counter_cache_spec.rb} +25 -1
- data/spec/integration/mongoid/association_spec.rb +24 -24
- data/spec/integration/rails2/association_spec.rb +49 -49
- data/spec/integration/rails2/{counter_spec.rb → counter_cache_spec.rb} +13 -1
- metadata +15 -14
- data/spec/bullet/detector/counter_spec.rb +0 -64
- data/spec/bullet/detector/unused_eager_association_spec.rb +0 -62
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b78d4be1915c82d239444c6ce93ecd347392a548
|
4
|
+
data.tar.gz: 907ad924dc1fcd98be89685253a62c8a06c9f445
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 845f8438dc5809f2420bd9a5a4735e07801c8f01f2d388aebc74421b543592c84afd2bcce299b7a531021c94f1180a4c23b8416145c25f187030026205e9abc6
|
7
|
+
data.tar.gz: 88160396803c47d86eaff8d5585af618f32f0aafd8d2f1f583071c7f604ded0c294d92cb4eff0cc5277dfdba1a8a578021bfd405ff3b0c5535844a24b9f0ff2c
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Next Release
|
2
|
+
|
3
|
+
## 4.5.0 (03/24/2013)
|
4
|
+
|
5
|
+
* Add api way to access captured associatioin
|
6
|
+
* Allow disable n_plus_one_query, unused_eager_loading and counter_cache respectively
|
7
|
+
* Add whitelist
|
8
|
+
|
9
|
+
## 4.4.0 (03/15/2013)
|
10
|
+
|
11
|
+
* Remove disable_browser_cache option
|
12
|
+
* Compatible with Rails 4.0.0.beta1
|
13
|
+
|
14
|
+
## 4.3.0 (12/28/2012)
|
15
|
+
|
16
|
+
* Fix content-length for non ascii html
|
17
|
+
* Add mongoid 2.5.x support
|
18
|
+
|
19
|
+
## 4.2.0 (09/29/2012)
|
20
|
+
|
21
|
+
* Add Bullet::Dependency to check AR and mongoid version
|
22
|
+
* Add Rails 4 support
|
23
|
+
* Add airbrake notifier support
|
24
|
+
|
25
|
+
## 4.1.0 (05/30/2012)
|
26
|
+
|
27
|
+
* Add mongoid 3 support
|
28
|
+
|
29
|
+
## 4.0.0 (05/09/2012)
|
30
|
+
|
31
|
+
* Add mongoid support
|
@@ -1,8 +1,10 @@
|
|
1
|
-
|
1
|
+
# Bullet Overview for Developers
|
2
|
+
|
2
3
|
This file aims to give developers a quick tour of the bullet internals, making
|
3
4
|
it (hopefully) easier to extend or enhance the Bullet gem.
|
4
5
|
|
5
|
-
|
6
|
+
## General Control Flow aka. 10000 Meter View
|
7
|
+
|
6
8
|
When Rails is initialized, Bullet will extend ActiveRecord (and if you're using
|
7
9
|
Rails 2.x ActiveController too) with the relevant modules and methods found
|
8
10
|
in lib/bullet/active_recordX.rb and lib/bullet/action_controller2.rb. If you're
|
@@ -36,7 +38,8 @@ So the flow of a request goes like this:
|
|
36
38
|
8. Bullet calls end_request for each detector.
|
37
39
|
9. Goto 1.
|
38
40
|
|
39
|
-
|
41
|
+
## Adding Notification Types
|
42
|
+
|
40
43
|
If you want to add more kinds of things that Bullet can detect, a little more
|
41
44
|
work is needed than if you were just adding a Presenter, but the concepts are
|
42
45
|
similar.
|
@@ -55,7 +58,8 @@ Since the detection of pathological associations is a bit hairy, I'd recommend
|
|
55
58
|
having a look at the counter cache detector and associated notification to get
|
56
59
|
a feel for what is needed to get off the ground.
|
57
60
|
|
58
|
-
|
61
|
+
### Detectors
|
62
|
+
|
59
63
|
The only things you'll need to consider when building your Detector class is
|
60
64
|
that it will need to supply the .start_request, .end_request and .clear class
|
61
65
|
methods.
|
@@ -63,7 +67,8 @@ methods.
|
|
63
67
|
Simple implementations are provided by Bullet::Detector::Base for start_request
|
64
68
|
and end_request, you will have to supply your own clear method.
|
65
69
|
|
66
|
-
|
70
|
+
### Notifications
|
71
|
+
|
67
72
|
For notifications you will want to supply a #title and #body instance method,
|
68
73
|
and check to see if the #initialize and #full_notice methods in the
|
69
74
|
Bullet::Notification::Base class fit your needs.
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# Bullet
|
2
2
|
|
3
3
|
!https://secure.travis-ci.org/flyerhzm/bullet.png!:http://travis-ci.org/flyerhzm/bullet
|
4
4
|
|
@@ -8,72 +8,92 @@ The Bullet gem is designed to help you increase your application's performance b
|
|
8
8
|
|
9
9
|
Best practice is to use Bullet in development mode or custom mode (staging, profile, etc.). The last thing you want is your clients getting alerts about how lazy you are.
|
10
10
|
|
11
|
-
The Bullet gem now supports **activerecord** 2.1, 2.2, 2.3, 3.0, 3.1,
|
11
|
+
The Bullet gem now supports **activerecord** 2.1, 2.2, 2.3, 3.0, 3.1,
|
12
|
+
3.2, 4.0 and **mongoid** >= 2.4.1.
|
12
13
|
|
13
|
-
|
14
|
+
## External Introduction
|
14
15
|
|
15
|
-
|
16
|
+
* [http://railscasts.com/episodes/372-bullet](http://railscasts.com/episodes/372-bullet)
|
17
|
+
* [http://ruby5.envylabs.com/episodes/9-episode-8-september-8-2009](http://ruby5.envylabs.com/episodes/9-episode-8-september-8-2009)
|
18
|
+
* [http://railslab.newrelic.com/2009/10/23/episode-19-on-the-edge-part-1](http://railslab.newrelic.com/2009/10/23/episode-19-on-the-edge-part-1)
|
19
|
+
* [http://weblog.rubyonrails.org/2009/10/22/community-highlights](http://weblog.rubyonrails.org/2009/10/22/community-highlights)
|
16
20
|
|
17
|
-
|
18
|
-
* "http://ruby5.envylabs.com/episodes/9-episode-8-september-8-2009":http://ruby5.envylabs.com/episodes/9-episode-8-september-8-2009
|
19
|
-
* "http://railslab.newrelic.com/2009/10/23/episode-19-on-the-edge-part-1":http://railslab.newrelic.com/2009/10/23/episode-19-on-the-edge-part-1
|
20
|
-
* "http://weblog.rubyonrails.org/2009/10/22/community-highlights":http://weblog.rubyonrails.org/2009/10/22/community-highlights
|
21
|
-
|
22
|
-
****************************************************************************
|
23
|
-
|
24
|
-
h2. Install
|
21
|
+
## Install
|
25
22
|
|
26
23
|
You can install it as a gem:
|
27
|
-
|
24
|
+
|
25
|
+
```
|
28
26
|
gem install bullet
|
29
|
-
|
27
|
+
|
28
|
+
```
|
30
29
|
|
31
30
|
or add it into a Gemfile (Bundler):
|
32
|
-
|
31
|
+
|
32
|
+
|
33
|
+
```ruby
|
33
34
|
gem "bullet", :group => "development"
|
34
|
-
|
35
|
+
```
|
35
36
|
|
36
|
-
|
37
|
+
## Configuration
|
37
38
|
|
38
|
-
|
39
|
+
Bullet won't do ANYTHING unless you tell it to explicitly. Append to
|
40
|
+
`config/environments/development.rb` initializer with the following code:
|
39
41
|
|
40
|
-
|
41
|
-
<pre><code>
|
42
|
+
```ruby
|
42
43
|
config.after_initialize do
|
43
44
|
Bullet.enable = true
|
44
|
-
Bullet.alert = true
|
45
|
-
Bullet.bullet_logger = true
|
45
|
+
Bullet.alert = true Bullet.bullet_logger = true
|
46
46
|
Bullet.console = true
|
47
47
|
Bullet.growl = true
|
48
|
-
Bullet.xmpp = { :account
|
48
|
+
Bullet.xmpp = { :account => 'bullets_account@jabber.org',
|
49
49
|
:password => 'bullets_password_for_jabber',
|
50
50
|
:receiver => 'your_account@jabber.org',
|
51
51
|
:show_online_status => true }
|
52
52
|
Bullet.rails_logger = true
|
53
53
|
Bullet.airbrake = true
|
54
54
|
end
|
55
|
-
|
55
|
+
```
|
56
56
|
|
57
|
-
The notifier of bullet is a wrap of
|
57
|
+
The notifier of bullet is a wrap of [uniform_notifier](https://github.com/flyerhzm/uniform_notifier)
|
58
58
|
|
59
59
|
The code above will enable all seven of the Bullet notification systems:
|
60
|
-
*
|
61
|
-
*
|
62
|
-
*
|
63
|
-
*
|
64
|
-
*
|
65
|
-
*
|
66
|
-
*
|
67
|
-
*
|
60
|
+
* `Bullet.enable`: enable Bullet gem, otherwise do nothing
|
61
|
+
* `Bullet.alert`: pop up a JavaScript alert in the browser
|
62
|
+
* `Bullet.bullet_logger`: log to the Bullet log file (Rails.root/log/bullet.log)
|
63
|
+
* `Bullet.rails_logger`: add warnings directly to the Rails log
|
64
|
+
* `Bullet.airbrake`: add notifications to airbrake
|
65
|
+
* `Bullet.console`: log warnings to your browser's console.log (Safari/Webkit browsers or Firefox w/Firebug installed)
|
66
|
+
* `Bullet.growl`: pop up Growl warnings if your system has Growl installed. Requires a little bit of configuration
|
67
|
+
* `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.
|
68
|
+
|
69
|
+
Bullet also allows you to disable n_plus_one_query, unused_eager_loading
|
70
|
+
and counter_cache detectors respectively
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
Bullet.n_plus_one_query_enable = false
|
74
|
+
Bullet.unused_eager_loading_enable = false
|
75
|
+
Bullet.counter_cache_enable = false
|
76
|
+
```
|
77
|
+
|
78
|
+
## Whitelist
|
68
79
|
|
69
|
-
|
80
|
+
Sometimes bullet may notify n plus one query, unused eager loading or
|
81
|
+
counter cache you don't care about or they occur in the third party gems
|
82
|
+
that you can't fix, you can add whitelist to bullet
|
70
83
|
|
71
|
-
|
84
|
+
```ruby
|
85
|
+
Bullet.add_whitelist :type => :n_plus_one_query, :class_name => "Post", :association => :comments
|
86
|
+
Bullet.add_whitelist :type => :unused_eager_loading, :class_name => "Post", :association => :comments
|
87
|
+
Bullet.add_whitelist :type => :counter_cache, :class_name => "Country", :association => :cities
|
88
|
+
```
|
72
89
|
|
73
|
-
|
90
|
+
## Log
|
91
|
+
|
92
|
+
The Bullet log `log/bullet.log` will look something like this:
|
74
93
|
|
75
94
|
* N+1 Query:
|
76
|
-
|
95
|
+
|
96
|
+
```
|
77
97
|
2009-08-25 20:40:17[INFO] N+1 Query: PATH_INFO: /posts; model: Post => associations: [comments]·
|
78
98
|
Add to your finder: :include => [:comments]
|
79
99
|
2009-08-25 20:40:17[INFO] N+1 Query: method call stack:·
|
@@ -81,54 +101,50 @@ Add to your finder: :include => [:comments]
|
|
81
101
|
/Users/richard/Downloads/test/app/views/posts/index.html.erb:8:in `each'
|
82
102
|
/Users/richard/Downloads/test/app/views/posts/index.html.erb:8:in `_run_erb_app47views47posts47index46html46erb'
|
83
103
|
/Users/richard/Downloads/test/app/controllers/posts_controller.rb:7:in `index'
|
84
|
-
|
104
|
+
```
|
85
105
|
|
86
106
|
The first two lines are notifications that N+1 queries have been encountered. The remaining lines are stack traces so you can find exactly where the queries were invoked in your code, and fix them.
|
87
107
|
|
88
108
|
* Unused eager loading:
|
89
|
-
|
109
|
+
|
110
|
+
```
|
90
111
|
2009-08-25 20:53:56[INFO] Unused eager loadings: PATH_INFO: /posts; model: Post => associations: [comments]·
|
91
112
|
Remove from your finder: :include => [:comments]
|
92
|
-
|
113
|
+
```
|
93
114
|
|
94
115
|
These two lines are notifications that unused eager loadings have been encountered.
|
95
116
|
|
96
117
|
* Need counter cache:
|
97
|
-
|
118
|
+
|
119
|
+
```
|
98
120
|
2009-09-11 09:46:50[INFO] Need Counter Cache
|
99
121
|
Post => [:comments]
|
100
|
-
|
101
|
-
|
102
|
-
****************************************************************************
|
122
|
+
```
|
103
123
|
|
104
|
-
|
124
|
+
## Growl, XMPP/Jabber and Airbrake Support
|
105
125
|
|
106
|
-
see
|
126
|
+
see [https://github.com/flyerhzm/uniform_notifier](https://github.com/flyerhzm/uniform_notifier)
|
107
127
|
|
108
|
-
|
109
|
-
|
110
|
-
h2. Important
|
128
|
+
## Important
|
111
129
|
|
112
130
|
If you find bullet does not work for you, *please disable your browser's cache*.
|
113
131
|
|
114
|
-
|
115
|
-
|
116
|
-
h2. Advance
|
132
|
+
## Advance
|
117
133
|
|
118
134
|
The bullet gem use rack middleware for http request. If you want to bullet for without http server, such as job server. You can do like this:
|
119
135
|
|
120
|
-
|
136
|
+
```ruby
|
121
137
|
Bullet.start_request if Bullet.enable?
|
122
138
|
# run job
|
123
139
|
if Bullet.enable? && Bullet.notification?
|
124
140
|
Bullet.perform_out_of_channel_notifications
|
125
141
|
end
|
126
142
|
Bullet.end_request if Bullet.enable?
|
127
|
-
|
143
|
+
```
|
128
144
|
|
129
145
|
Or you want to use it in test mode
|
130
146
|
|
131
|
-
|
147
|
+
```ruby
|
132
148
|
before(:each)
|
133
149
|
Bullet.start_request if Bullet.enable?
|
134
150
|
end
|
@@ -139,35 +155,45 @@ after(:each)
|
|
139
155
|
end
|
140
156
|
Bullet.end_request if Bullet.enable?
|
141
157
|
end
|
142
|
-
|
158
|
+
```
|
143
159
|
|
144
160
|
Don't forget enabling bullet in test environment.
|
145
161
|
|
146
|
-
|
162
|
+
### API access
|
147
163
|
|
148
|
-
|
164
|
+
after `end_request`, you can fetch warnings then do whatever you want
|
165
|
+
|
166
|
+
```ruby
|
167
|
+
Bullet.start_request if Bullet.enable?
|
168
|
+
# run anything
|
169
|
+
if Bullet.enable? && Bullet.notification?
|
170
|
+
Bullet.perform_out_of_channel_notifications
|
171
|
+
end
|
172
|
+
Bullet.end_request if Bullet.enable?
|
173
|
+
warnings = Bullet.warnings
|
174
|
+
```
|
149
175
|
|
150
|
-
|
176
|
+
## Contributors
|
151
177
|
|
152
|
-
|
178
|
+
[https://github.com/flyerhzm/bullet/contributors](https://github.com/flyerhzm/bullet/contributors)
|
153
179
|
|
154
|
-
|
180
|
+
## Step by step example
|
155
181
|
|
156
182
|
Bullet is designed to function as you browse through your application in development. It will alert you whenever it encounters N+1 queries or unused eager loading.
|
157
183
|
|
158
|
-
1
|
184
|
+
1\. setup test environment
|
159
185
|
|
160
|
-
|
186
|
+
```
|
161
187
|
$ rails new test_bullet
|
162
188
|
$ cd test_bullet
|
163
189
|
$ rails g scaffold post name:string
|
164
190
|
$ rails g scaffold comment name:string post_id:integer
|
165
191
|
$ bundle exec rake db:migrate
|
166
|
-
|
192
|
+
```
|
167
193
|
|
168
|
-
2
|
194
|
+
2\. change `app/model/post.rb` and `app/model/comment.rb`
|
169
195
|
|
170
|
-
|
196
|
+
```ruby
|
171
197
|
class Post < ActiveRecord::Base
|
172
198
|
has_many :comments
|
173
199
|
end
|
@@ -175,22 +201,22 @@ end
|
|
175
201
|
class Comment < ActiveRecord::Base
|
176
202
|
belongs_to :post
|
177
203
|
end
|
178
|
-
|
204
|
+
```
|
179
205
|
|
180
|
-
3
|
206
|
+
3\. go to `rails c` and execute
|
181
207
|
|
182
|
-
|
208
|
+
```ruby
|
183
209
|
post1 = Post.create(:name => 'first')
|
184
210
|
post2 = Post.create(:name => 'second')
|
185
211
|
post1.comments.create(:name => 'first')
|
186
212
|
post1.comments.create(:name => 'second')
|
187
213
|
post2.comments.create(:name => 'third')
|
188
214
|
post2.comments.create(:name => 'fourth')
|
189
|
-
|
215
|
+
```
|
190
216
|
|
191
|
-
4
|
217
|
+
4\. change the `app/views/posts/index.html.erb` to produce a N+1 query
|
192
218
|
|
193
|
-
|
219
|
+
```
|
194
220
|
<% @posts.each do |post| %>
|
195
221
|
<tr>
|
196
222
|
<td><%= post.name %></td>
|
@@ -200,21 +226,24 @@ post2.comments.create(:name => 'fourth')
|
|
200
226
|
<td><%= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete %></td>
|
201
227
|
</tr>
|
202
228
|
<% end %>
|
203
|
-
|
229
|
+
```
|
204
230
|
|
205
|
-
5
|
231
|
+
5\. add bullet gem to `Gemfile`
|
206
232
|
|
207
|
-
|
233
|
+
```ruby
|
208
234
|
gem "bullet"
|
209
|
-
|
235
|
+
```
|
210
236
|
|
211
237
|
And run
|
212
238
|
|
213
|
-
|
239
|
+
```
|
240
|
+
bundle install
|
241
|
+
```
|
214
242
|
|
215
|
-
6
|
243
|
+
6\. enable the bullet gem in development, add a line to
|
244
|
+
`config/environments/development.rb`
|
216
245
|
|
217
|
-
|
246
|
+
```ruby
|
218
247
|
config.after_initialize do
|
219
248
|
Bullet.enable = true
|
220
249
|
Bullet.alert = true
|
@@ -223,28 +252,28 @@ config.after_initialize do
|
|
223
252
|
# Bullet.growl = true
|
224
253
|
Bullet.rails_logger = true
|
225
254
|
end
|
226
|
-
|
255
|
+
```
|
227
256
|
|
228
|
-
7
|
257
|
+
7\. start server
|
229
258
|
|
230
|
-
|
259
|
+
```
|
231
260
|
$ rails s
|
232
|
-
|
261
|
+
```
|
233
262
|
|
234
|
-
8
|
263
|
+
8\. input http://localhost:3000/posts in browser, then you will see a popup alert box says
|
235
264
|
|
236
|
-
|
265
|
+
```
|
237
266
|
The request has unused preload associations as follows:
|
238
267
|
None
|
239
268
|
The request has N+1 queries as follows:
|
240
269
|
model: Post => associations: [comment]
|
241
|
-
|
270
|
+
```
|
242
271
|
|
243
272
|
which means there is a N+1 query from post object to comments associations.
|
244
273
|
|
245
|
-
In the meanwhile, there's a log appended into
|
274
|
+
In the meanwhile, there's a log appended into `log/bullet.log` file
|
246
275
|
|
247
|
-
|
276
|
+
```
|
248
277
|
2010-03-07 14:12:18[INFO] N+1 Query in /posts
|
249
278
|
Post => [:comments]
|
250
279
|
Add to your finder: :include => [:comments]
|
@@ -253,55 +282,57 @@ In the meanwhile, there's a log appended into <code>log/bullet.log</code> file
|
|
253
282
|
/home/flyerhzm/Downloads/test_bullet/app/views/posts/index.html.erb:11:in `each'
|
254
283
|
/home/flyerhzm/Downloads/test_bullet/app/views/posts/index.html.erb:11:in `_render_template__600522146_80203160_0'
|
255
284
|
/home/flyerhzm/Downloads/test_bullet/app/controllers/posts_controller.rb:7:in `index'
|
256
|
-
|
285
|
+
```
|
257
286
|
|
258
287
|
The generated SQLs are
|
259
288
|
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
289
|
+
```
|
290
|
+
Post Load (1.0ms) SELECT * FROM "posts"
|
291
|
+
Comment Load (0.4ms) SELECT * FROM "comments" WHERE ("comments".post_id = 1)
|
292
|
+
Comment Load (0.3ms) SELECT * FROM "comments" WHERE ("comments".post_id = 2)
|
293
|
+
```
|
265
294
|
|
266
295
|
|
267
|
-
9
|
296
|
+
9\. fix the N+1 query, change `app/controllers/posts_controller.rb` file
|
268
297
|
|
269
|
-
|
270
|
-
|
271
|
-
|
298
|
+
```ruby
|
299
|
+
def index
|
300
|
+
@posts = Post.includes(:comments)
|
272
301
|
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
end
|
302
|
+
respond_to do |format|
|
303
|
+
format.html # index.html.erb
|
304
|
+
format.xml { render :xml => @posts }
|
277
305
|
end
|
278
|
-
|
306
|
+
end
|
307
|
+
```
|
279
308
|
|
280
|
-
10
|
309
|
+
10\. refresh http://localhost:3000/posts page, no alert box and no log appended.
|
281
310
|
|
282
311
|
The generated SQLs are
|
283
312
|
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
313
|
+
```
|
314
|
+
Post Load (0.5ms) SELECT * FROM "posts"
|
315
|
+
Comment Load (0.5ms) SELECT "comments".* FROM "comments" WHERE ("comments".post_id IN (1,2))
|
316
|
+
```
|
288
317
|
|
289
318
|
a N+1 query fixed. Cool!
|
290
319
|
|
291
|
-
11
|
320
|
+
11\. now simulate unused eager loading. Change
|
321
|
+
`app/controllers/posts_controller.rb` and
|
322
|
+
`app/views/posts/index.html.erb`
|
292
323
|
|
293
|
-
|
294
|
-
|
295
|
-
|
324
|
+
```ruby
|
325
|
+
def index
|
326
|
+
@posts = Post.includes(:comments)
|
296
327
|
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
end
|
328
|
+
respond_to do |format|
|
329
|
+
format.html # index.html.erb
|
330
|
+
format.xml { render :xml => @posts }
|
301
331
|
end
|
302
|
-
|
332
|
+
end
|
333
|
+
```
|
303
334
|
|
304
|
-
|
335
|
+
```
|
305
336
|
<% @posts.each do |post| %>
|
306
337
|
<tr>
|
307
338
|
<td><%= post.name %></td>
|
@@ -310,38 +341,39 @@ a N+1 query fixed. Cool!
|
|
310
341
|
<td><%= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete %></td>
|
311
342
|
</tr>
|
312
343
|
<% end %>
|
313
|
-
|
344
|
+
```
|
314
345
|
|
315
|
-
12
|
346
|
+
12\. refresh http://localhost:3000/posts page, then you will see a popup alert box says
|
316
347
|
|
317
|
-
|
348
|
+
```
|
318
349
|
The request has unused preload associations as follows:
|
319
350
|
model: Post => associations: [comment]
|
320
351
|
The request has N+1 queries as follows:
|
321
352
|
None
|
322
|
-
|
353
|
+
```
|
323
354
|
|
324
|
-
In the meanwhile, there's a log appended into
|
355
|
+
In the meanwhile, there's a log appended into `log/bullet.log` file
|
325
356
|
|
326
|
-
|
357
|
+
```
|
327
358
|
2009-08-25 21:13:22[INFO] Unused preload associations: PATH_INFO: /posts; model: Post => associations: [comments]·
|
328
359
|
Remove from your finder: :include => [:comments]
|
329
|
-
|
360
|
+
```
|
330
361
|
|
331
|
-
13
|
362
|
+
13\. simulate counter_cache. Change `app/controllers/posts_controller.rb`
|
363
|
+
and `app/views/posts/index.html.erb`
|
332
364
|
|
333
|
-
|
334
|
-
|
335
|
-
|
365
|
+
```ruby
|
366
|
+
def index
|
367
|
+
@posts = Post.all
|
336
368
|
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
end
|
369
|
+
respond_to do |format|
|
370
|
+
format.html # index.html.erb
|
371
|
+
format.xml { render :xml => @posts }
|
341
372
|
end
|
342
|
-
|
373
|
+
end
|
374
|
+
```
|
343
375
|
|
344
|
-
|
376
|
+
```
|
345
377
|
<% @posts.each do |post| %>
|
346
378
|
<tr>
|
347
379
|
<td><%= post.name %></td>
|
@@ -351,23 +383,21 @@ Remove from your finder: :include => [:comments]
|
|
351
383
|
<td><%= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete %></td>
|
352
384
|
</tr>
|
353
385
|
<% end %>
|
354
|
-
|
386
|
+
```
|
355
387
|
|
356
|
-
14
|
388
|
+
14\. refresh http://localhost:3000/posts page, then you will see a popup alert box says
|
357
389
|
|
358
|
-
|
390
|
+
```
|
359
391
|
Need counter cache
|
360
392
|
Post => [:comments]
|
361
|
-
|
393
|
+
```
|
362
394
|
|
363
|
-
In the meanwhile, there's a log appended into
|
395
|
+
In the meanwhile, there's a log appended into `log/bullet.log` file.
|
364
396
|
|
365
|
-
|
397
|
+
```
|
366
398
|
2009-09-11 10:07:10[INFO] Need Counter Cache
|
367
399
|
Post => [:comments]
|
368
|
-
|
369
|
-
|
370
|
-
****************************************************************************
|
400
|
+
```
|
371
401
|
|
372
402
|
|
373
403
|
Copyright (c) 2009 - 2013 Richard Huang (flyerhzm@gmail.com), released under the MIT license
|