bullet 2.0.1 → 2.1.0
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.
- 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
|