bullet 2.0.1 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.rvmrc +2 -0
- data/.rvmrc.example +2 -0
- data/.watchr +24 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +105 -0
- data/Hacking.textile +69 -0
- data/README.textile +37 -55
- data/README_for_rails2.textile +35 -52
- data/Rakefile +45 -0
- data/bullet.gemspec +24 -0
- data/lib/bullet.rb +5 -5
- data/lib/bullet/action_controller2.rb +5 -5
- data/lib/bullet/active_record2.rb +2 -1
- data/lib/bullet/active_record3.rb +2 -1
- data/lib/bullet/active_record31.rb +96 -0
- data/lib/bullet/detector/association.rb +18 -9
- data/lib/bullet/detector/base.rb +0 -7
- data/lib/bullet/detector/unused_eager_association.rb +7 -5
- data/lib/bullet/notification/base.rb +6 -2
- data/lib/bullet/rack.rb +1 -1
- data/lib/bullet/registry/association.rb +1 -2
- data/lib/bullet/registry/base.rb +6 -8
- data/lib/bullet/version.rb +1 -1
- data/perf/benchmark.rb +106 -0
- data/rails/init.rb +1 -0
- data/spec/bullet/association_for_chris_spec.rb +96 -0
- data/spec/bullet/association_for_peschkaj_spec.rb +86 -0
- data/spec/bullet/association_spec.rb +889 -0
- data/spec/bullet/counter_spec.rb +136 -0
- data/spec/spec_helper.rb +79 -0
- data/tasks/bullet_tasks.rake +9 -0
- metadata +59 -62
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rvmrc
ADDED
data/.rvmrc.example
ADDED
data/.watchr
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# vim:set filetype=ruby:
|
2
|
+
def run(cmd)
|
3
|
+
puts cmd
|
4
|
+
system cmd
|
5
|
+
end
|
6
|
+
|
7
|
+
def spec(file)
|
8
|
+
if File.exists?(file)
|
9
|
+
run("rspec #{file}")
|
10
|
+
else
|
11
|
+
puts("Spec: #{file} does not exist.")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
watch("spec/.*/*_spec\.rb") do |match|
|
16
|
+
puts(match[0])
|
17
|
+
spec(match[0])
|
18
|
+
end
|
19
|
+
|
20
|
+
watch("lib/(.*/.*)\.rb") do |match|
|
21
|
+
puts(match[1])
|
22
|
+
spec("spec/#{match[1]}_spec.rb")
|
23
|
+
end
|
24
|
+
|
data/Gemfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# Use `bundle install` in order to install these gems
|
2
|
+
# Use `bundle exec rake` in order to run the specs using the bundle
|
3
|
+
source "http://rubygems.org"
|
4
|
+
|
5
|
+
gemspec
|
6
|
+
|
7
|
+
gem 'rails'
|
8
|
+
gem 'sqlite3-ruby', :require => 'sqlite3'
|
9
|
+
gem 'mysql'
|
10
|
+
gem 'activerecord-import'
|
11
|
+
|
12
|
+
gem "rspec"
|
13
|
+
gem "watchr"
|
14
|
+
|
15
|
+
gem "perftools.rb"
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
bullet (2.1.0)
|
5
|
+
uniform_notifier (~> 1.0.0)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
specs:
|
10
|
+
abstract (1.0.0)
|
11
|
+
actionmailer (3.0.11)
|
12
|
+
actionpack (= 3.0.11)
|
13
|
+
mail (~> 2.2.19)
|
14
|
+
actionpack (3.0.11)
|
15
|
+
activemodel (= 3.0.11)
|
16
|
+
activesupport (= 3.0.11)
|
17
|
+
builder (~> 2.1.2)
|
18
|
+
erubis (~> 2.6.6)
|
19
|
+
i18n (~> 0.5.0)
|
20
|
+
rack (~> 1.2.1)
|
21
|
+
rack-mount (~> 0.6.14)
|
22
|
+
rack-test (~> 0.5.7)
|
23
|
+
tzinfo (~> 0.3.23)
|
24
|
+
activemodel (3.0.11)
|
25
|
+
activesupport (= 3.0.11)
|
26
|
+
builder (~> 2.1.2)
|
27
|
+
i18n (~> 0.5.0)
|
28
|
+
activerecord (3.0.11)
|
29
|
+
activemodel (= 3.0.11)
|
30
|
+
activesupport (= 3.0.11)
|
31
|
+
arel (~> 2.0.10)
|
32
|
+
tzinfo (~> 0.3.23)
|
33
|
+
activerecord-import (0.2.5)
|
34
|
+
activerecord (~> 3.0.0)
|
35
|
+
activeresource (3.0.11)
|
36
|
+
activemodel (= 3.0.11)
|
37
|
+
activesupport (= 3.0.11)
|
38
|
+
activesupport (3.0.11)
|
39
|
+
arel (2.0.10)
|
40
|
+
builder (2.1.2)
|
41
|
+
diff-lcs (1.1.3)
|
42
|
+
erubis (2.6.6)
|
43
|
+
abstract (>= 1.0.0)
|
44
|
+
i18n (0.5.0)
|
45
|
+
json (1.6.3)
|
46
|
+
mail (2.2.19)
|
47
|
+
activesupport (>= 2.3.6)
|
48
|
+
i18n (>= 0.4.0)
|
49
|
+
mime-types (~> 1.16)
|
50
|
+
treetop (~> 1.4.8)
|
51
|
+
mime-types (1.17.2)
|
52
|
+
mysql (2.8.1)
|
53
|
+
perftools.rb (0.5.6)
|
54
|
+
polyglot (0.3.3)
|
55
|
+
rack (1.2.4)
|
56
|
+
rack-mount (0.6.14)
|
57
|
+
rack (>= 1.0.0)
|
58
|
+
rack-test (0.5.7)
|
59
|
+
rack (>= 1.0)
|
60
|
+
rails (3.0.11)
|
61
|
+
actionmailer (= 3.0.11)
|
62
|
+
actionpack (= 3.0.11)
|
63
|
+
activerecord (= 3.0.11)
|
64
|
+
activeresource (= 3.0.11)
|
65
|
+
activesupport (= 3.0.11)
|
66
|
+
bundler (~> 1.0)
|
67
|
+
railties (= 3.0.11)
|
68
|
+
railties (3.0.11)
|
69
|
+
actionpack (= 3.0.11)
|
70
|
+
activesupport (= 3.0.11)
|
71
|
+
rake (>= 0.8.7)
|
72
|
+
rdoc (~> 3.4)
|
73
|
+
thor (~> 0.14.4)
|
74
|
+
rake (0.9.2.2)
|
75
|
+
rdoc (3.11)
|
76
|
+
json (~> 1.4)
|
77
|
+
rspec (2.7.0)
|
78
|
+
rspec-core (~> 2.7.0)
|
79
|
+
rspec-expectations (~> 2.7.0)
|
80
|
+
rspec-mocks (~> 2.7.0)
|
81
|
+
rspec-core (2.7.1)
|
82
|
+
rspec-expectations (2.7.0)
|
83
|
+
diff-lcs (~> 1.1.2)
|
84
|
+
rspec-mocks (2.7.0)
|
85
|
+
sqlite3-ruby (1.3.2)
|
86
|
+
thor (0.14.6)
|
87
|
+
treetop (1.4.10)
|
88
|
+
polyglot
|
89
|
+
polyglot (>= 0.3.1)
|
90
|
+
tzinfo (0.3.31)
|
91
|
+
uniform_notifier (1.0.1)
|
92
|
+
watchr (0.7)
|
93
|
+
|
94
|
+
PLATFORMS
|
95
|
+
ruby
|
96
|
+
|
97
|
+
DEPENDENCIES
|
98
|
+
activerecord-import
|
99
|
+
bullet!
|
100
|
+
mysql
|
101
|
+
perftools.rb
|
102
|
+
rails
|
103
|
+
rspec
|
104
|
+
sqlite3-ruby
|
105
|
+
watchr
|
data/Hacking.textile
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
h1. Bullet Overview for Developers
|
2
|
+
This file aims to give developers a quick tour of the bullet internals, making
|
3
|
+
it (hopefully) easier to extend or enhance the Bullet gem.
|
4
|
+
|
5
|
+
h2. General Control Flow aka. 10000 Meter View
|
6
|
+
When Rails is initialized, Bullet will extend ActiveRecord (and if you're using
|
7
|
+
Rails 2.x ActiveController too) with the relevant modules and methods found
|
8
|
+
in lib/bullet/active_recordX.rb and lib/bullet/action_controller2.rb. If you're
|
9
|
+
running Rails 3, Bullet will integrate itself as a middleware into the Rack
|
10
|
+
stack, so ActionController does not need to be extended.
|
11
|
+
|
12
|
+
The ActiveRecord extensions will call methods in a given detector class, when
|
13
|
+
certain methods are called.
|
14
|
+
|
15
|
+
Detector classes contain all the logic to recognize
|
16
|
+
a noteworthy event. If such an event is detected, an instance of the
|
17
|
+
corresponding Notification class is created and stored in a Set instance in the
|
18
|
+
main Bullet module (the 'notification collector').
|
19
|
+
|
20
|
+
Notification instances contain the message that will be displayed, and will
|
21
|
+
use a Presenter class to display their message to the user.
|
22
|
+
|
23
|
+
So the flow of a request goes like this:
|
24
|
+
1. Bullet.start_request is called, which resets all the detectors and empties
|
25
|
+
the notification collector
|
26
|
+
2. The request is handled by Rails, and the installed ActiveRecord extensions
|
27
|
+
trigger Detector callbacks
|
28
|
+
3. Detectors once called, will determine whether something noteworthy happend.
|
29
|
+
If yes, then a Notification is created and stored in the notification collector.
|
30
|
+
4. Rails finishes handling the request
|
31
|
+
5. For each notification in the collector, Bullet will iterate over each
|
32
|
+
Presenter and will try to generate an inline message that will be appended to
|
33
|
+
the generated response body.
|
34
|
+
6. The response is returned to the client.
|
35
|
+
7. Bullet will try to generate an out-of-channel message for each notification.
|
36
|
+
8. Bullet calls end_request for each detector.
|
37
|
+
9. Goto 1.
|
38
|
+
|
39
|
+
h2. Adding Notification Types
|
40
|
+
If you want to add more kinds of things that Bullet can detect, a little more
|
41
|
+
work is needed than if you were just adding a Presenter, but the concepts are
|
42
|
+
similar.
|
43
|
+
|
44
|
+
* Add the class to the DETECTORS constant in the main Bullet module
|
45
|
+
* Add (if needed) Rails monkey patches to Bullet.enable
|
46
|
+
* Add an autoload directive to lib/bullet/detector.rb
|
47
|
+
* Create a corresponding notification class in the Bullet::Notification namespace
|
48
|
+
* Add an autoload directive to lib/bullet/notification.rb
|
49
|
+
|
50
|
+
As a rule of thumb, you can assume that each Detector will have its own
|
51
|
+
Notification class. If you follow the principle of Separation of Concerns I
|
52
|
+
can't really think of an example where one would deviate from this rule.
|
53
|
+
|
54
|
+
Since the detection of pathological associations is a bit hairy, I'd recommend
|
55
|
+
having a look at the counter cache detector and associated notification to get
|
56
|
+
a feel for what is needed to get off the ground.
|
57
|
+
|
58
|
+
h3. Detectors
|
59
|
+
The only things you'll need to consider when building your Detector class is
|
60
|
+
that it will need to supply the .start_request, .end_request and .clear class
|
61
|
+
methods.
|
62
|
+
|
63
|
+
Simple implementations are provided by Bullet::Detector::Base for start_request
|
64
|
+
and end_request, you will have to supply your own clear method.
|
65
|
+
|
66
|
+
h3. Notifications
|
67
|
+
For notifications you will want to supply a #title and #body instance method,
|
68
|
+
and check to see if the #initialize and #full_notice methods in the
|
69
|
+
Bullet::Notification::Base class fit your needs.
|
data/README.textile
CHANGED
@@ -4,20 +4,22 @@ The Bullet plugin/gem is designed to help you increase your application's perfor
|
|
4
4
|
|
5
5
|
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.
|
6
6
|
|
7
|
-
The Bullet plugin/gem now supports rails 2.1, 2.2, 2.3 and 3.0
|
7
|
+
The Bullet plugin/gem now supports rails 2.1, 2.2, 2.3 and 3.0.
|
8
8
|
|
9
9
|
****************************************************************************
|
10
10
|
|
11
11
|
h2. Install
|
12
12
|
|
13
|
-
You can add Bullet to your Rails gem requirements:
|
14
|
-
<pre><code>config.gem 'bullet', :source => 'http://gemcutter.org'</code></pre>
|
15
|
-
|
16
13
|
You can install it as a gem:
|
17
14
|
<pre><code>
|
18
|
-
|
15
|
+
gem install bullet
|
19
16
|
</code></pre>
|
20
17
|
|
18
|
+
or add it into a Gemfile (Bundler):
|
19
|
+
<pre><code>
|
20
|
+
gem "bullet", :group => "development"
|
21
|
+
</code></code>
|
22
|
+
|
21
23
|
****************************************************************************
|
22
24
|
|
23
25
|
h2. Configuration
|
@@ -25,9 +27,9 @@ h2. Configuration
|
|
25
27
|
Bullet won't do ANYTHING unless you tell it to explicitly. Append to <code>config/environments/development.rb</code> initializer with the following code:
|
26
28
|
<pre><code>
|
27
29
|
config.after_initialize do
|
28
|
-
Bullet.enable = true
|
30
|
+
Bullet.enable = true
|
29
31
|
Bullet.alert = true
|
30
|
-
Bullet.bullet_logger = true
|
32
|
+
Bullet.bullet_logger = true
|
31
33
|
Bullet.console = true
|
32
34
|
Bullet.growl = true
|
33
35
|
Bullet.xmpp = { :account => 'bullets_account@jabber.org',
|
@@ -39,27 +41,7 @@ config.after_initialize do
|
|
39
41
|
end
|
40
42
|
</code></pre>
|
41
43
|
|
42
|
-
|
43
|
-
<pre><code>
|
44
|
-
begin
|
45
|
-
require 'ruby-growl'
|
46
|
-
Bullet.growl = true
|
47
|
-
rescue MissingSourceFile
|
48
|
-
end
|
49
|
-
</code></pre>
|
50
|
-
|
51
|
-
and similarly for XMPP:
|
52
|
-
<pre><code>
|
53
|
-
begin
|
54
|
-
require 'xmpp4r'
|
55
|
-
Bullet.xmpp = { :account => 'bullets_account@jabber.org',
|
56
|
-
:password => 'bullets_password_for_jabber',
|
57
|
-
:receiver => 'your_account@jabber.org',
|
58
|
-
:show_online_status => true }
|
59
|
-
rescue MissingSourceFile
|
60
|
-
end
|
61
|
-
</code></pre>
|
62
|
-
|
44
|
+
The notifier of bullet is a wrap of "uniform_notifier":https://github.com/flyerhzm/uniform_notifier
|
63
45
|
|
64
46
|
The code above will enable all six of the Bullet notification systems:
|
65
47
|
* <code>Bullet.enable</code>: enable Bullet plugin/gem, otherwise do nothing
|
@@ -109,10 +91,10 @@ These two lines are notifications that unused eager loadings have been encounter
|
|
109
91
|
h2. Growl Support
|
110
92
|
|
111
93
|
To get Growl support up-and-running for Bullet, follow the steps below:
|
112
|
-
* Install the ruby-growl gem: <code>
|
94
|
+
* Install the ruby-growl gem: <code>gem install ruby-growl</code>
|
113
95
|
* Open the Growl preference pane in Systems Preferences
|
114
96
|
* Click the "Network" tab
|
115
|
-
* Make sure both "Listen for incoming notifications" and "Allow remote application registration" are checked. *Note*: If you set a password, you will need to set <code>Bullet.
|
97
|
+
* Make sure both "Listen for incoming notifications" and "Allow remote application registration" are checked. *Note*: If you set a password, you will need to set <code>Bullet.growl = { :password => 'growl password' }</code> in the config file.
|
116
98
|
* Restart Growl ("General" tab -> Stop Growl -> Start Growl)
|
117
99
|
* Boot up your application. Bullet will automatically send a Growl notification when Growl is turned on. If you do not see it when your application loads, make sure it is enabled in your initializer and double-check the steps above.
|
118
100
|
|
@@ -198,11 +180,11 @@ Bullet is designed to function as you browse through your application in develop
|
|
198
180
|
1. setup test environment
|
199
181
|
|
200
182
|
<pre><code>
|
201
|
-
$ rails
|
202
|
-
$ cd
|
203
|
-
$
|
204
|
-
$
|
205
|
-
$ rake db:migrate
|
183
|
+
$ rails new test_bullet
|
184
|
+
$ cd test_bullet
|
185
|
+
$ rails g scaffold post name:string
|
186
|
+
$ rails g scaffold comment name:string post_id:integer
|
187
|
+
$ bundle exec rake db:migrate
|
206
188
|
</code></pre>
|
207
189
|
|
208
190
|
2. change <code>app/model/post.rb</code> and <code>app/model/comment.rb</code>
|
@@ -217,7 +199,7 @@ class Comment < ActiveRecord::Base
|
|
217
199
|
end
|
218
200
|
</code></pre>
|
219
201
|
|
220
|
-
3. go to <code>
|
202
|
+
3. go to <code>rails c</code> and execute
|
221
203
|
|
222
204
|
<pre><code>
|
223
205
|
post1 = Post.create(:name => 'first')
|
@@ -234,7 +216,7 @@ post2.comments.create(:name => 'fourth')
|
|
234
216
|
<% @posts.each do |post| %>
|
235
217
|
<tr>
|
236
218
|
<td><%= post.name %></td>
|
237
|
-
<td><%= post.comments.
|
219
|
+
<td><%= post.comments.map(&:name) %></td>
|
238
220
|
<td><%= link_to 'Show', post %></td>
|
239
221
|
<td><%= link_to 'Edit', edit_post_path(post) %></td>
|
240
222
|
<td><%= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete %></td>
|
@@ -245,7 +227,7 @@ post2.comments.create(:name => 'fourth')
|
|
245
227
|
5. add bullet gem to <code>Gemfile</code>
|
246
228
|
|
247
229
|
<pre><code>
|
248
|
-
gem "bullet"
|
230
|
+
gem "bullet"
|
249
231
|
</code></pre>
|
250
232
|
|
251
233
|
And run
|
@@ -269,7 +251,7 @@ end
|
|
269
251
|
7. start server
|
270
252
|
|
271
253
|
<pre><code>
|
272
|
-
$
|
254
|
+
$ rails s
|
273
255
|
</code></pre>
|
274
256
|
|
275
257
|
8. input http://localhost:3000/posts in browser, then you will see a popup alert box says
|
@@ -290,18 +272,18 @@ In the meanwhile, there's a log appended into <code>log/bullet.log</code> file
|
|
290
272
|
Post => [:comments]
|
291
273
|
Add to your finder: :include => [:comments]
|
292
274
|
2010-03-07 14:12:18[INFO] N+1 Query method call stack
|
293
|
-
/home/flyerhzm/
|
294
|
-
/home/flyerhzm/
|
295
|
-
/home/flyerhzm/
|
296
|
-
/home/flyerhzm/
|
275
|
+
/home/flyerhzm/Downloads/test_bullet/app/views/posts/index.html.erb:14:in `_render_template__600522146_80203160_0'
|
276
|
+
/home/flyerhzm/Downloads/test_bullet/app/views/posts/index.html.erb:11:in `each'
|
277
|
+
/home/flyerhzm/Downloads/test_bullet/app/views/posts/index.html.erb:11:in `_render_template__600522146_80203160_0'
|
278
|
+
/home/flyerhzm/Downloads/test_bullet/app/controllers/posts_controller.rb:7:in `index'
|
297
279
|
</code></pre>
|
298
280
|
|
299
281
|
The generated SQLs are
|
300
282
|
|
301
283
|
<pre><code>
|
302
|
-
Post Load (1.0ms) SELECT * FROM "posts"
|
303
|
-
Comment Load (0.4ms) SELECT * FROM "comments" WHERE ("comments".post_id = 1)
|
304
|
-
Comment Load (0.3ms) SELECT * FROM "comments" WHERE ("comments".post_id = 2)
|
284
|
+
Post Load (1.0ms) SELECT * FROM "posts"
|
285
|
+
Comment Load (0.4ms) SELECT * FROM "comments" WHERE ("comments".post_id = 1)
|
286
|
+
Comment Load (0.3ms) SELECT * FROM "comments" WHERE ("comments".post_id = 2)
|
305
287
|
</code></pre>
|
306
288
|
|
307
289
|
|
@@ -314,8 +296,8 @@ The generated SQLs are
|
|
314
296
|
respond_to do |format|
|
315
297
|
format.html # index.html.erb
|
316
298
|
format.xml { render :xml => @posts }
|
317
|
-
end
|
318
|
-
end
|
299
|
+
end
|
300
|
+
end
|
319
301
|
</code></pre>
|
320
302
|
|
321
303
|
10. refresh http://localhost:3000/posts page, no alert box and no log appended.
|
@@ -323,8 +305,8 @@ The generated SQLs are
|
|
323
305
|
The generated SQLs are
|
324
306
|
|
325
307
|
<pre><code>
|
326
|
-
Post Load (0.5ms) SELECT * FROM "posts"
|
327
|
-
Comment Load (0.5ms) SELECT "comments".* FROM "comments" WHERE ("comments".post_id IN (1,2))
|
308
|
+
Post Load (0.5ms) SELECT * FROM "posts"
|
309
|
+
Comment Load (0.5ms) SELECT "comments".* FROM "comments" WHERE ("comments".post_id IN (1,2))
|
328
310
|
</code></pre>
|
329
311
|
|
330
312
|
a N+1 query fixed. Cool!
|
@@ -338,8 +320,8 @@ a N+1 query fixed. Cool!
|
|
338
320
|
respond_to do |format|
|
339
321
|
format.html # index.html.erb
|
340
322
|
format.xml { render :xml => @posts }
|
341
|
-
end
|
342
|
-
end
|
323
|
+
end
|
324
|
+
end
|
343
325
|
</code></pre>
|
344
326
|
|
345
327
|
<pre><code>
|
@@ -378,8 +360,8 @@ Remove from your finder: :include => [:comments]
|
|
378
360
|
respond_to do |format|
|
379
361
|
format.html # index.html.erb
|
380
362
|
format.xml { render :xml => @posts }
|
381
|
-
end
|
382
|
-
end
|
363
|
+
end
|
364
|
+
end
|
383
365
|
</code></pre>
|
384
366
|
|
385
367
|
<pre><code>
|
@@ -411,4 +393,4 @@ In the meanwhile, there's a log appended into <code>log/bullet.log</code> file.
|
|
411
393
|
****************************************************************************
|
412
394
|
|
413
395
|
|
414
|
-
Copyright (c) 2009 -
|
396
|
+
Copyright (c) 2009 - 2011 Richard Huang (flyerhzm@gmail.com), released under the MIT license
|
data/README_for_rails2.textile
CHANGED
@@ -6,8 +6,6 @@ Best practice is to use Bullet in development mode or custom mode (staging, prof
|
|
6
6
|
|
7
7
|
The Bullet plugin/gem now supports rails 2.1, 2.2 and 2.3, tested in rails 2.1.2, 2.2.2 and 2.3.2.
|
8
8
|
|
9
|
-
*Important: bullet gem has been moved to gemcutter.org*
|
10
|
-
|
11
9
|
****************************************************************************
|
12
10
|
|
13
11
|
h2. Change
|
@@ -27,18 +25,11 @@ rainux added group style console.log.
|
|
27
25
|
|
28
26
|
h2. Install
|
29
27
|
|
30
|
-
You can add Bullet to your Rails gem requirements:
|
31
|
-
<pre><code>config.gem 'bullet', :source => 'http://gemcutter.org'</code></pre>
|
32
|
-
|
33
28
|
You can install it as a gem:
|
34
29
|
<pre><code>
|
35
|
-
sudo gem sources -a http://gemcutter.org
|
36
30
|
sudo gem install bullet
|
37
31
|
</code></pre>
|
38
32
|
|
39
|
-
Or you can install it as a rails plugin:
|
40
|
-
<pre><code>script/plugin install git://github.com/flyerhzm/bullet.git</code></pre>
|
41
|
-
|
42
33
|
****************************************************************************
|
43
34
|
|
44
35
|
h2. Configuration
|
@@ -46,9 +37,9 @@ h2. Configuration
|
|
46
37
|
Bullet won't do ANYTHING unless you tell it to explicitly. Append to <code>config/environments/development.rb</code> initializer with the following code:
|
47
38
|
<pre><code>
|
48
39
|
config.after_initialize do
|
49
|
-
Bullet.enable = true
|
40
|
+
Bullet.enable = true
|
50
41
|
Bullet.alert = true
|
51
|
-
Bullet.bullet_logger = true
|
42
|
+
Bullet.bullet_logger = true
|
52
43
|
Bullet.console = true
|
53
44
|
Bullet.growl = true
|
54
45
|
Bullet.rails_logger = true
|
@@ -60,26 +51,7 @@ config.after_initialize do
|
|
60
51
|
end
|
61
52
|
</code></pre>
|
62
53
|
|
63
|
-
|
64
|
-
<pre><code>
|
65
|
-
begin
|
66
|
-
require 'ruby-growl'
|
67
|
-
Bullet.growl = true
|
68
|
-
rescue MissingSourceFile
|
69
|
-
end
|
70
|
-
</code></pre>
|
71
|
-
|
72
|
-
and similarly for XMPP:
|
73
|
-
<pre><code>
|
74
|
-
begin
|
75
|
-
require 'xmpp4r'
|
76
|
-
Bullet.xmpp = { :account => 'bullets_account@jabber.org',
|
77
|
-
:password => 'bullets_password_for_jabber',
|
78
|
-
:receiver => 'your_account@jabber.org',
|
79
|
-
:show_online_status => true }
|
80
|
-
rescue MissingSourceFile
|
81
|
-
end
|
82
|
-
</code></pre>
|
54
|
+
The notifier of bullet is a wrap of "uniform_notifier":https://github.com/flyerhzm/uniform_notifier
|
83
55
|
|
84
56
|
The code above will enable all five of the Bullet notification systems:
|
85
57
|
* <code>Bullet.enable</code>: enable Bullet plugin/gem, otherwise do nothing
|
@@ -128,10 +100,10 @@ These two lines are notifications that unused eager loadings have been encounter
|
|
128
100
|
h2. Growl Support
|
129
101
|
|
130
102
|
To get Growl support up-and-running for Bullet, follow the steps below:
|
131
|
-
* Install the ruby-growl gem: <code>
|
103
|
+
* Install the ruby-growl gem: <code>gem install ruby-growl</code>
|
132
104
|
* Open the Growl preference pane in Systems Preferences
|
133
105
|
* Click the "Network" tab
|
134
|
-
* Make sure both "Listen for incoming notifications" and "Allow remote application registration" are checked. *Note*: If you set a password, you will need to set <code>Bullet.
|
106
|
+
* Make sure both "Listen for incoming notifications" and "Allow remote application registration" are checked. *Note*: If you set a password, you will need to set <code>Bullet.growl = { :password => 'growl password' }</code> in the config file.
|
135
107
|
* Restart Growl ("General" tab -> Stop Growl -> Start Growl)
|
136
108
|
* Boot up your application. Bullet will automatically send a Growl notification when Growl is turned on. If you do not see it when your application loads, make sure it is enabled in your initializer and double-check the steps above.
|
137
109
|
|
@@ -143,6 +115,17 @@ ruby-growl gem has an issue about md5 in ruby 1.9, if you use growl and ruby 1.9
|
|
143
115
|
|
144
116
|
****************************************************************************
|
145
117
|
|
118
|
+
h2. XMPP/Jabber Support
|
119
|
+
|
120
|
+
To get XMPP support up-and-running for Bullet, follow the steps below:
|
121
|
+
* Install the xmpp4r gem: <code>sudo gem install xmpp4r</code>
|
122
|
+
* Make both the bullet and the receipient account add each other as contacts.
|
123
|
+
This will require you to manually log into both accounts, add each other
|
124
|
+
as contact and confirm each others contact request.
|
125
|
+
* Boot up your application. Bullet will automatically send an XMPP notification when XMPP is turned on.
|
126
|
+
|
127
|
+
****************************************************************************
|
128
|
+
|
146
129
|
h2. Important
|
147
130
|
|
148
131
|
If you encounter the following errors in development environment:
|
@@ -209,9 +192,9 @@ Bullet is designed to function as you browse through your application in develop
|
|
209
192
|
1. setup test environment
|
210
193
|
|
211
194
|
<pre><code>
|
212
|
-
$ rails
|
213
|
-
$ cd
|
214
|
-
$ script/generate scaffold post name:string
|
195
|
+
$ rails test_bullet
|
196
|
+
$ cd test_bullet
|
197
|
+
$ script/generate scaffold post name:string
|
215
198
|
$ script/generate scaffold comment name:string post_id:integer
|
216
199
|
$ rake db:migrate
|
217
200
|
</code></pre>
|
@@ -296,18 +279,18 @@ In the meanwhile, there's a log appended into <code>log/bullet.log</code> file
|
|
296
279
|
2009-08-20 09:12:19[INFO] N+1 Query: PATH_INFO: /posts; model: Post => assocations: [comments]
|
297
280
|
Add your finder: :include => [:comments]
|
298
281
|
2009-08-20 09:12:19[INFO] N+1 Query: method call stack:
|
299
|
-
/Users/
|
300
|
-
/Users/
|
301
|
-
/Users/
|
302
|
-
/Users/
|
282
|
+
/Users/flyerhzm/Downloads/test_bullet/app/views/posts/index.html.erb:11:in `_run_erb_app47views47posts47index46html46erb'
|
283
|
+
/Users/flyerhzm/Downloads/test_bullet/app/views/posts/index.html.erb:8:in `each'
|
284
|
+
/Users/flyerhzm/Downloads/test_bullet/app/views/posts/index.html.erb:8:in `_run_erb_app47views47posts47index46html46erb'
|
285
|
+
/Users/flyerhzm/Downloads/test_bullet/app/controllers/posts_controller.rb:7:in `index'
|
303
286
|
</code></pre>
|
304
287
|
|
305
288
|
The generated SQLs are
|
306
289
|
|
307
290
|
<pre><code>
|
308
|
-
Post Load (1.0ms) SELECT * FROM "posts"
|
309
|
-
Comment Load (0.4ms) SELECT * FROM "comments" WHERE ("comments".post_id = 1)
|
310
|
-
Comment Load (0.3ms) SELECT * FROM "comments" WHERE ("comments".post_id = 2)
|
291
|
+
Post Load (1.0ms) SELECT * FROM "posts"
|
292
|
+
Comment Load (0.4ms) SELECT * FROM "comments" WHERE ("comments".post_id = 1)
|
293
|
+
Comment Load (0.3ms) SELECT * FROM "comments" WHERE ("comments".post_id = 2)
|
311
294
|
</code></pre>
|
312
295
|
|
313
296
|
|
@@ -320,8 +303,8 @@ The generated SQLs are
|
|
320
303
|
respond_to do |format|
|
321
304
|
format.html # index.html.erb
|
322
305
|
format.xml { render :xml => @posts }
|
323
|
-
end
|
324
|
-
end
|
306
|
+
end
|
307
|
+
end
|
325
308
|
</code></pre>
|
326
309
|
|
327
310
|
10. refresh http://localhost:3000/posts page, no alert box and no log appended.
|
@@ -329,8 +312,8 @@ The generated SQLs are
|
|
329
312
|
The generated SQLs are
|
330
313
|
|
331
314
|
<pre><code>
|
332
|
-
Post Load (0.5ms) SELECT * FROM "posts"
|
333
|
-
Comment Load (0.5ms) SELECT "comments".* FROM "comments" WHERE ("comments".post_id IN (1,2))
|
315
|
+
Post Load (0.5ms) SELECT * FROM "posts"
|
316
|
+
Comment Load (0.5ms) SELECT "comments".* FROM "comments" WHERE ("comments".post_id IN (1,2))
|
334
317
|
</code></pre>
|
335
318
|
|
336
319
|
a N+1 query fixed. Cool!
|
@@ -344,8 +327,8 @@ a N+1 query fixed. Cool!
|
|
344
327
|
respond_to do |format|
|
345
328
|
format.html # index.html.erb
|
346
329
|
format.xml { render :xml => @posts }
|
347
|
-
end
|
348
|
-
end
|
330
|
+
end
|
331
|
+
end
|
349
332
|
</code></pre>
|
350
333
|
|
351
334
|
<pre><code>
|
@@ -384,8 +367,8 @@ Remove from your finder: :include => [:comments]
|
|
384
367
|
respond_to do |format|
|
385
368
|
format.html # index.html.erb
|
386
369
|
format.xml { render :xml => @posts }
|
387
|
-
end
|
388
|
-
end
|
370
|
+
end
|
371
|
+
end
|
389
372
|
</code></pre>
|
390
373
|
|
391
374
|
<pre><code>
|
@@ -417,4 +400,4 @@ In the meanwhile, there's a log appended into <code>log/bullet.log</code> file.
|
|
417
400
|
****************************************************************************
|
418
401
|
|
419
402
|
|
420
|
-
Copyright (c) 2009 -
|
403
|
+
Copyright (c) 2009 - 2011 Richard Huang (flyerhzm@gmail.com), released under the MIT license
|