bullet 4.0.0 → 4.13.1

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.
Files changed (112) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.rspec +1 -1
  4. data/.travis.yml +17 -6
  5. data/CHANGELOG.md +86 -0
  6. data/Gemfile +13 -12
  7. data/Gemfile.mongoid +14 -0
  8. data/Gemfile.mongoid-2.4 +19 -0
  9. data/Gemfile.mongoid-2.5 +19 -0
  10. data/Gemfile.mongoid-2.6 +19 -0
  11. data/Gemfile.mongoid-2.7 +19 -0
  12. data/Gemfile.mongoid-2.8 +19 -0
  13. data/Gemfile.mongoid-3.0 +19 -0
  14. data/Gemfile.mongoid-3.1 +19 -0
  15. data/Gemfile.mongoid-4.0 +19 -0
  16. data/Gemfile.rails-3.0 +19 -0
  17. data/Gemfile.rails-3.1 +19 -0
  18. data/Gemfile.rails-3.2 +19 -0
  19. data/Gemfile.rails-4.0 +19 -0
  20. data/Gemfile.rails-4.1 +19 -0
  21. data/{Hacking.textile → Hacking.md} +10 -5
  22. data/README.md +432 -0
  23. data/Rakefile +13 -6
  24. data/bullet.gemspec +6 -3
  25. data/lib/bullet/active_record3.rb +49 -11
  26. data/lib/bullet/active_record3x.rb +134 -0
  27. data/lib/bullet/{active_record31.rb → active_record4.rb} +45 -15
  28. data/lib/bullet/active_record41.rb +128 -0
  29. data/lib/bullet/dependency.rb +81 -0
  30. data/lib/bullet/detector/association.rb +24 -68
  31. data/lib/bullet/detector/base.rb +0 -6
  32. data/lib/bullet/detector/counter_cache.rb +59 -0
  33. data/lib/bullet/detector/n_plus_one_query.rb +56 -15
  34. data/lib/bullet/detector/unused_eager_loading.rb +84 -0
  35. data/lib/bullet/detector.rb +2 -2
  36. data/lib/bullet/ext/object.rb +10 -2
  37. data/lib/bullet/{mongoid.rb → mongoid2x.rb} +18 -18
  38. data/lib/bullet/mongoid3x.rb +56 -0
  39. data/lib/bullet/mongoid4x.rb +56 -0
  40. data/lib/bullet/notification/base.rb +22 -4
  41. data/lib/bullet/notification/n_plus_one_query.rb +1 -1
  42. data/lib/bullet/notification.rb +2 -0
  43. data/lib/bullet/rack.rb +51 -17
  44. data/lib/bullet/registry/base.rb +1 -1
  45. data/lib/bullet/registry/object.rb +4 -4
  46. data/lib/bullet/version.rb +1 -2
  47. data/lib/bullet.rb +119 -39
  48. data/perf/benchmark.rb +1 -4
  49. data/spec/bullet/detector/association_spec.rb +2 -70
  50. data/spec/bullet/detector/base_spec.rb +0 -6
  51. data/spec/bullet/detector/counter_cache_spec.rb +56 -0
  52. data/spec/bullet/detector/n_plus_one_query_spec.rb +78 -34
  53. data/spec/bullet/detector/unused_eager_loading_spec.rb +88 -0
  54. data/spec/bullet/ext/object_spec.rb +18 -7
  55. data/spec/bullet/ext/string_spec.rb +2 -2
  56. data/spec/bullet/notification/base_spec.rb +68 -15
  57. data/spec/bullet/notification/counter_cache_spec.rb +2 -2
  58. data/spec/bullet/notification/n_plus_one_query_spec.rb +4 -3
  59. data/spec/bullet/notification/unused_eager_loading_spec.rb +2 -2
  60. data/spec/bullet/notification_collector_spec.rb +4 -4
  61. data/spec/bullet/rack_spec.rb +40 -39
  62. data/spec/bullet/registry/association_spec.rb +3 -3
  63. data/spec/bullet/registry/base_spec.rb +6 -6
  64. data/spec/bullet/registry/object_spec.rb +4 -5
  65. data/spec/bullet_spec.rb +41 -0
  66. data/spec/integration/active_record3/association_spec.rb +662 -0
  67. data/spec/integration/active_record4/association_spec.rb +660 -0
  68. data/spec/integration/counter_cache_spec.rb +63 -0
  69. data/spec/integration/mongoid/association_spec.rb +190 -208
  70. data/spec/models/category.rb +1 -1
  71. data/spec/models/client.rb +1 -1
  72. data/spec/models/comment.rb +2 -2
  73. data/spec/models/document.rb +2 -2
  74. data/spec/models/firm.rb +1 -1
  75. data/spec/models/mongoid/address.rb +2 -0
  76. data/spec/models/mongoid/category.rb +2 -0
  77. data/spec/models/mongoid/comment.rb +2 -0
  78. data/spec/models/mongoid/company.rb +2 -0
  79. data/spec/models/mongoid/entry.rb +2 -0
  80. data/spec/models/mongoid/post.rb +4 -0
  81. data/spec/models/mongoid/user.rb +5 -0
  82. data/spec/models/newspaper.rb +1 -1
  83. data/spec/models/pet.rb +1 -1
  84. data/spec/models/post.rb +6 -13
  85. data/spec/spec_helper.rb +60 -25
  86. data/spec/support/bullet_ext.rb +1 -1
  87. data/spec/support/mongo_seed.rb +26 -2
  88. data/spec/support/sqlite_seed.rb +0 -6
  89. data/test.sh +15 -0
  90. metadata +77 -54
  91. data/.rvmrc +0 -2
  92. data/.rvmrc.example +0 -2
  93. data/Gemfile.lock +0 -132
  94. data/Gemfile.rails-2.3.14 +0 -16
  95. data/Gemfile.rails-2.3.14.lock +0 -65
  96. data/Gemfile.rails-3.0.12 +0 -17
  97. data/Gemfile.rails-3.0.12.lock +0 -116
  98. data/Gemfile.rails-3.1.4 +0 -18
  99. data/Gemfile.rails-3.1.4.lock +0 -134
  100. data/README.textile +0 -395
  101. data/README_for_rails2.textile +0 -400
  102. data/lib/bullet/action_controller2.rb +0 -49
  103. data/lib/bullet/active_record2.rb +0 -121
  104. data/lib/bullet/detector/counter.rb +0 -48
  105. data/lib/bullet/detector/unused_eager_association.rb +0 -42
  106. data/spec/bullet/detector/counter_spec.rb +0 -64
  107. data/spec/bullet/detector/unused_eager_association_spec.rb +0 -62
  108. data/spec/integration/association_spec.rb +0 -593
  109. data/spec/integration/counter_spec.rb +0 -39
  110. data/spec/integration/rails2/association_spec.rb +0 -593
  111. data/spec/integration/rails2/counter_spec.rb +0 -39
  112. data/test.result +0 -2293
data/Gemfile.rails-3.0.12 DELETED
@@ -1,17 +0,0 @@
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', '3.0.12'
8
- gem 'sqlite3'
9
- gem 'mysql'
10
- gem 'activerecord-import'
11
- gem 'bson_ext'
12
-
13
- gem "rspec"
14
- gem "guard"
15
- gem "guard-rspec"
16
-
17
- gem "perftools.rb"
@@ -1,116 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- bullet (2.3.1)
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.12)
12
- actionpack (= 3.0.12)
13
- mail (~> 2.2.19)
14
- actionpack (3.0.12)
15
- activemodel (= 3.0.12)
16
- activesupport (= 3.0.12)
17
- builder (~> 2.1.2)
18
- erubis (~> 2.6.6)
19
- i18n (~> 0.5.0)
20
- rack (~> 1.2.5)
21
- rack-mount (~> 0.6.14)
22
- rack-test (~> 0.5.7)
23
- tzinfo (~> 0.3.23)
24
- activemodel (3.0.12)
25
- activesupport (= 3.0.12)
26
- builder (~> 2.1.2)
27
- i18n (~> 0.5.0)
28
- activerecord (3.0.12)
29
- activemodel (= 3.0.12)
30
- activesupport (= 3.0.12)
31
- arel (~> 2.0.10)
32
- tzinfo (~> 0.3.23)
33
- activerecord-import (0.2.9)
34
- activerecord (~> 3.0)
35
- activerecord (~> 3.0)
36
- activeresource (3.0.12)
37
- activemodel (= 3.0.12)
38
- activesupport (= 3.0.12)
39
- activesupport (3.0.12)
40
- arel (2.0.10)
41
- bson (1.6.2)
42
- bson_ext (1.6.2)
43
- bson (~> 1.6.2)
44
- builder (2.1.2)
45
- diff-lcs (1.1.3)
46
- erubis (2.6.6)
47
- abstract (>= 1.0.0)
48
- ffi (1.0.11)
49
- guard (1.0.2)
50
- ffi (>= 0.5.0)
51
- thor (~> 0.14.6)
52
- guard-rspec (0.7.0)
53
- guard (>= 0.10.0)
54
- i18n (0.5.0)
55
- json (1.7.0)
56
- mail (2.2.19)
57
- activesupport (>= 2.3.6)
58
- i18n (>= 0.4.0)
59
- mime-types (~> 1.16)
60
- treetop (~> 1.4.8)
61
- mime-types (1.18)
62
- mysql (2.8.1)
63
- perftools.rb (2.0.0)
64
- polyglot (0.3.3)
65
- rack (1.2.5)
66
- rack-mount (0.6.14)
67
- rack (>= 1.0.0)
68
- rack-test (0.5.7)
69
- rack (>= 1.0)
70
- rails (3.0.12)
71
- actionmailer (= 3.0.12)
72
- actionpack (= 3.0.12)
73
- activerecord (= 3.0.12)
74
- activeresource (= 3.0.12)
75
- activesupport (= 3.0.12)
76
- bundler (~> 1.0)
77
- railties (= 3.0.12)
78
- railties (3.0.12)
79
- actionpack (= 3.0.12)
80
- activesupport (= 3.0.12)
81
- rake (>= 0.8.7)
82
- rdoc (~> 3.4)
83
- thor (~> 0.14.4)
84
- rake (0.9.2.2)
85
- rdoc (3.12)
86
- json (~> 1.4)
87
- rspec (2.10.0)
88
- rspec-core (~> 2.10.0)
89
- rspec-expectations (~> 2.10.0)
90
- rspec-mocks (~> 2.10.0)
91
- rspec-core (2.10.0)
92
- rspec-expectations (2.10.0)
93
- diff-lcs (~> 1.1.3)
94
- rspec-mocks (2.10.1)
95
- sqlite3 (1.3.6)
96
- thor (0.14.6)
97
- treetop (1.4.10)
98
- polyglot
99
- polyglot (>= 0.3.1)
100
- tzinfo (0.3.33)
101
- uniform_notifier (1.0.2)
102
-
103
- PLATFORMS
104
- ruby
105
-
106
- DEPENDENCIES
107
- activerecord-import
108
- bson_ext
109
- bullet!
110
- guard
111
- guard-rspec
112
- mysql
113
- perftools.rb
114
- rails (= 3.0.12)
115
- rspec
116
- sqlite3
data/Gemfile.rails-3.1.4 DELETED
@@ -1,18 +0,0 @@
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', '3.1.4'
8
- gem 'sqlite3'
9
- gem 'mysql'
10
- gem 'activerecord-import'
11
- gem 'mongoid'
12
- gem 'bson_ext'
13
-
14
- gem "rspec"
15
- gem "guard"
16
- gem "guard-rspec"
17
-
18
- gem "perftools.rb"
@@ -1,134 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- bullet (2.3.1)
5
- uniform_notifier (~> 1.0.0)
6
-
7
- GEM
8
- remote: http://rubygems.org/
9
- specs:
10
- actionmailer (3.1.4)
11
- actionpack (= 3.1.4)
12
- mail (~> 2.3.0)
13
- actionpack (3.1.4)
14
- activemodel (= 3.1.4)
15
- activesupport (= 3.1.4)
16
- builder (~> 3.0.0)
17
- erubis (~> 2.7.0)
18
- i18n (~> 0.6)
19
- rack (~> 1.3.6)
20
- rack-cache (~> 1.1)
21
- rack-mount (~> 0.8.2)
22
- rack-test (~> 0.6.1)
23
- sprockets (~> 2.0.3)
24
- activemodel (3.1.4)
25
- activesupport (= 3.1.4)
26
- builder (~> 3.0.0)
27
- i18n (~> 0.6)
28
- activerecord (3.1.4)
29
- activemodel (= 3.1.4)
30
- activesupport (= 3.1.4)
31
- arel (~> 2.2.3)
32
- tzinfo (~> 0.3.29)
33
- activerecord-import (0.2.9)
34
- activerecord (~> 3.0)
35
- activerecord (~> 3.0)
36
- activeresource (3.1.4)
37
- activemodel (= 3.1.4)
38
- activesupport (= 3.1.4)
39
- activesupport (3.1.4)
40
- multi_json (~> 1.0)
41
- arel (2.2.3)
42
- bson (1.6.2)
43
- bson_ext (1.6.2)
44
- bson (~> 1.6.2)
45
- builder (3.0.0)
46
- diff-lcs (1.1.3)
47
- erubis (2.7.0)
48
- ffi (1.0.11)
49
- guard (1.0.2)
50
- ffi (>= 0.5.0)
51
- thor (~> 0.14.6)
52
- guard-rspec (0.7.0)
53
- guard (>= 0.10.0)
54
- hike (1.2.1)
55
- i18n (0.6.0)
56
- json (1.7.1)
57
- mail (2.3.3)
58
- i18n (>= 0.4.0)
59
- mime-types (~> 1.16)
60
- treetop (~> 1.4.8)
61
- mime-types (1.18)
62
- mongo (1.6.2)
63
- bson (~> 1.6.2)
64
- mongoid (2.4.9)
65
- activemodel (~> 3.1)
66
- mongo (~> 1.3)
67
- tzinfo (~> 0.3.22)
68
- multi_json (1.3.4)
69
- mysql (2.8.1)
70
- perftools.rb (2.0.0)
71
- polyglot (0.3.3)
72
- rack (1.3.6)
73
- rack-cache (1.2)
74
- rack (>= 0.4)
75
- rack-mount (0.8.3)
76
- rack (>= 1.0.0)
77
- rack-ssl (1.3.2)
78
- rack
79
- rack-test (0.6.1)
80
- rack (>= 1.0)
81
- rails (3.1.4)
82
- actionmailer (= 3.1.4)
83
- actionpack (= 3.1.4)
84
- activerecord (= 3.1.4)
85
- activeresource (= 3.1.4)
86
- activesupport (= 3.1.4)
87
- bundler (~> 1.0)
88
- railties (= 3.1.4)
89
- railties (3.1.4)
90
- actionpack (= 3.1.4)
91
- activesupport (= 3.1.4)
92
- rack-ssl (~> 1.3.2)
93
- rake (>= 0.8.7)
94
- rdoc (~> 3.4)
95
- thor (~> 0.14.6)
96
- rake (0.9.2.2)
97
- rdoc (3.12)
98
- json (~> 1.4)
99
- rspec (2.10.0)
100
- rspec-core (~> 2.10.0)
101
- rspec-expectations (~> 2.10.0)
102
- rspec-mocks (~> 2.10.0)
103
- rspec-core (2.10.0)
104
- rspec-expectations (2.10.0)
105
- diff-lcs (~> 1.1.3)
106
- rspec-mocks (2.10.1)
107
- sprockets (2.0.4)
108
- hike (~> 1.2)
109
- rack (~> 1.0)
110
- tilt (~> 1.1, != 1.3.0)
111
- sqlite3 (1.3.6)
112
- thor (0.14.6)
113
- tilt (1.3.3)
114
- treetop (1.4.10)
115
- polyglot
116
- polyglot (>= 0.3.1)
117
- tzinfo (0.3.33)
118
- uniform_notifier (1.0.2)
119
-
120
- PLATFORMS
121
- ruby
122
-
123
- DEPENDENCIES
124
- activerecord-import
125
- bson_ext
126
- bullet!
127
- guard
128
- guard-rspec
129
- mongoid
130
- mysql
131
- perftools.rb
132
- rails (= 3.1.4)
133
- rspec
134
- sqlite3
data/README.textile DELETED
@@ -1,395 +0,0 @@
1
- h1. Bullet !https://gemnasium.com/flyerhzm/bullet.png?travis(Dependency Status)!:https://gemnasium.com/flyerhzm/bullet
2
-
3
- !https://secure.travis-ci.org/flyerhzm/bullet.png!:http://travis-ci.org/flyerhzm/bullet
4
-
5
- The Bullet gem is designed to help you increase your application's performance by reducing the number of queries it makes. It will watch your queries while you develop your application and notify you when you should add eager loading (N+1 queries), when you're using eager loading that isn't necessary and when you should use counter cache.
6
-
7
- 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.
8
-
9
- The Bullet gem now supports **activerecord** 2.1, 2.2, 2.3, 3.0, 3.1, 3.2 and **mongoid** >= 2.4.1.
10
-
11
- ****************************************************************************
12
-
13
- h2. Install
14
-
15
- You can install it as a gem:
16
- <pre><code>
17
- gem install bullet
18
- </code></pre>
19
-
20
- or add it into a Gemfile (Bundler):
21
- <pre><code>
22
- gem "bullet", :group => "development"
23
- </code></pre>
24
-
25
- ****************************************************************************
26
-
27
- h2. Configuration
28
-
29
- Bullet won't do ANYTHING unless you tell it to explicitly. Append to <code>config/environments/development.rb</code> initializer with the following code:
30
- <pre><code>
31
- config.after_initialize do
32
- Bullet.enable = true
33
- Bullet.alert = true
34
- Bullet.bullet_logger = true
35
- Bullet.console = true
36
- Bullet.growl = true
37
- Bullet.xmpp = { :account => 'bullets_account@jabber.org',
38
- :password => 'bullets_password_for_jabber',
39
- :receiver => 'your_account@jabber.org',
40
- :show_online_status => true }
41
- Bullet.rails_logger = true
42
- Bullet.disable_browser_cache = true
43
- end
44
- </code></pre>
45
-
46
- The notifier of bullet is a wrap of "uniform_notifier":https://github.com/flyerhzm/uniform_notifier
47
-
48
- The code above will enable all six of the Bullet notification systems:
49
- * <code>Bullet.enable</code>: enable Bullet gem, otherwise do nothing
50
- * <code>Bullet.alert</code>: pop up a JavaScript alert in the browser
51
- * <code>Bullet.bullet_logger</code>: log to the Bullet log file (Rails.root/log/bullet.log)
52
- * <code>Bullet.rails_logger</code>: add warnings directly to the Rails log
53
- * <code>Bullet.console</code>: log warnings to your browser's console.log (Safari/Webkit browsers or Firefox w/Firebug installed)
54
- * <code>Bullet.growl</code>: pop up Growl warnings if your system has Growl installed. Requires a little bit of configuration
55
- * <code>Bullet.xmpp</code>: 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.
56
- * <code>Bullet.disable_browser_cache</code>: disable browser cache which usually causes unexpected problems
57
-
58
- ****************************************************************************
59
-
60
- h2. Log
61
-
62
- The Bullet log <code>log/bullet.log</code> will look something like this:
63
-
64
- * N+1 Query:
65
- <pre><code>
66
- 2009-08-25 20:40:17[INFO] N+1 Query: PATH_INFO: /posts; model: Post => associations: [comments]·
67
- Add to your finder: :include => [:comments]
68
- 2009-08-25 20:40:17[INFO] N+1 Query: method call stack:·
69
- /Users/richard/Downloads/test/app/views/posts/index.html.erb:11:in `_run_erb_app47views47posts47index46html46erb'
70
- /Users/richard/Downloads/test/app/views/posts/index.html.erb:8:in `each'
71
- /Users/richard/Downloads/test/app/views/posts/index.html.erb:8:in `_run_erb_app47views47posts47index46html46erb'
72
- /Users/richard/Downloads/test/app/controllers/posts_controller.rb:7:in `index'
73
- </code></pre>
74
-
75
- 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.
76
-
77
- * Unused eager loading:
78
- <pre><code>
79
- 2009-08-25 20:53:56[INFO] Unused eager loadings: PATH_INFO: /posts; model: Post => associations: [comments]·
80
- Remove from your finder: :include => [:comments]
81
- </code></pre>
82
-
83
- These two lines are notifications that unused eager loadings have been encountered.
84
-
85
- * Need counter cache:
86
- <pre><code>
87
- 2009-09-11 09:46:50[INFO] Need Counter Cache
88
- Post => [:comments]
89
- </code></pre>
90
-
91
- ****************************************************************************
92
-
93
- h2. Growl Support
94
-
95
- To get Growl support up-and-running for Bullet, follow the steps below:
96
- * Install the ruby-growl gem: <code>gem install ruby-growl</code>
97
- * Open the Growl preference pane in Systems Preferences
98
- * Click the "Network" tab
99
- * 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.
100
- * Restart Growl ("General" tab -> Stop Growl -> Start Growl)
101
- * 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.
102
-
103
- ****************************************************************************
104
-
105
- h2. Ruby 1.9 issue
106
-
107
- ruby-growl gem has an issue about md5 in ruby 1.9, if you use growl and ruby 1.9, check this gist http://gist.github.com/300184
108
-
109
- ****************************************************************************
110
-
111
- h2. XMPP/Jabber Support
112
-
113
- To get XMPP support up-and-running for Bullet, follow the steps below:
114
- * Install the xmpp4r gem: <code>sudo gem install xmpp4r</code>
115
- * Make both the bullet and the receipient account add each other as contacts.
116
- This will require you to manually log into both accounts, add each other
117
- as contact and confirm each others contact request.
118
- * Boot up your application. Bullet will automatically send an XMPP notification when XMPP is turned on.
119
-
120
- ****************************************************************************
121
-
122
- h2. Important
123
-
124
- If you find bullet does not work for you, *please disable your browser's cache*.
125
-
126
- ****************************************************************************
127
-
128
- h2. Advance
129
-
130
- 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:
131
-
132
- <pre><code>
133
- Bullet.start_request if Bullet.enable?
134
- # run job
135
- if Bullet.enable?
136
- Bullet.growl_notification
137
- Bullet.log_notification('JobServer: ')
138
- Bullet.end_request
139
- end
140
- </code></pre>
141
-
142
- Or you want to use it in test mode
143
-
144
- <pre><code>
145
- before(:each)
146
- Bullet.start_request if Bullet.enable?
147
- end
148
-
149
- after(:each)
150
- if Bullet.enable?
151
- Bullet.perform_out_of_channel_notifications
152
- Bullet.end_request
153
- end
154
- end
155
- </code></pre>
156
-
157
- Don't forget enabling bullet in test environment.
158
-
159
- ****************************************************************************
160
-
161
- h2. Links
162
-
163
- * "http://weblog.rubyonrails.org/2009/10/22/community-highlights":http://weblog.rubyonrails.org/2009/10/22/community-highlights
164
- * "http://ruby5.envylabs.com/episodes/9-episode-8-september-8-2009":http://ruby5.envylabs.com/episodes/9-episode-8-september-8-2009
165
- * "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
166
-
167
- ****************************************************************************
168
-
169
- h2. Contributors
170
-
171
- "https://github.com/flyerhzm/bullet/contributors":https://github.com/flyerhzm/bullet/contributors
172
-
173
- ****************************************************************************
174
-
175
- h2. Step by step example
176
-
177
- 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.
178
-
179
- 1. setup test environment
180
-
181
- <pre><code>
182
- $ rails new test_bullet
183
- $ cd test_bullet
184
- $ rails g scaffold post name:string
185
- $ rails g scaffold comment name:string post_id:integer
186
- $ bundle exec rake db:migrate
187
- </code></pre>
188
-
189
- 2. change <code>app/model/post.rb</code> and <code>app/model/comment.rb</code>
190
-
191
- <pre><code>
192
- class Post < ActiveRecord::Base
193
- has_many :comments
194
- end
195
-
196
- class Comment < ActiveRecord::Base
197
- belongs_to :post
198
- end
199
- </code></pre>
200
-
201
- 3. go to <code>rails c</code> and execute
202
-
203
- <pre><code>
204
- post1 = Post.create(:name => 'first')
205
- post2 = Post.create(:name => 'second')
206
- post1.comments.create(:name => 'first')
207
- post1.comments.create(:name => 'second')
208
- post2.comments.create(:name => 'third')
209
- post2.comments.create(:name => 'fourth')
210
- </code></pre>
211
-
212
- 4. change the <code>app/views/posts/index.html.erb</code> to produce a N+1 query
213
-
214
- <pre><code>
215
- <% @posts.each do |post| %>
216
- <tr>
217
- <td><%= post.name %></td>
218
- <td><%= post.comments.map(&:name) %></td>
219
- <td><%= link_to 'Show', post %></td>
220
- <td><%= link_to 'Edit', edit_post_path(post) %></td>
221
- <td><%= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete %></td>
222
- </tr>
223
- <% end %>
224
- </code></pre>
225
-
226
- 5. add bullet gem to <code>Gemfile</code>
227
-
228
- <pre><code>
229
- gem "bullet"
230
- </code></pre>
231
-
232
- And run
233
-
234
- <pre><code>bundle install</code></pre>
235
-
236
- 6. enable the bullet gem in development, add a line to <code>config/environments/development.rb</code>
237
-
238
- <pre><code>
239
- config.after_initialize do
240
- Bullet.enable = true
241
- Bullet.alert = true
242
- Bullet.bullet_logger = true
243
- Bullet.console = true
244
- # Bullet.growl = true
245
- Bullet.rails_logger = true
246
- Bullet.disable_browser_cache = true
247
- end
248
- </code></pre>
249
-
250
- 7. start server
251
-
252
- <pre><code>
253
- $ rails s
254
- </code></pre>
255
-
256
- 8. input http://localhost:3000/posts in browser, then you will see a popup alert box says
257
-
258
- <pre><code>
259
- The request has unused preload associations as follows:
260
- None
261
- The request has N+1 queries as follows:
262
- model: Post => associations: [comment]
263
- </code></pre>
264
-
265
- which means there is a N+1 query from post object to comments associations.
266
-
267
- In the meanwhile, there's a log appended into <code>log/bullet.log</code> file
268
-
269
- <pre><code>
270
- 2010-03-07 14:12:18[INFO] N+1 Query in /posts
271
- Post => [:comments]
272
- Add to your finder: :include => [:comments]
273
- 2010-03-07 14:12:18[INFO] N+1 Query method call stack
274
- /home/flyerhzm/Downloads/test_bullet/app/views/posts/index.html.erb:14:in `_render_template__600522146_80203160_0'
275
- /home/flyerhzm/Downloads/test_bullet/app/views/posts/index.html.erb:11:in `each'
276
- /home/flyerhzm/Downloads/test_bullet/app/views/posts/index.html.erb:11:in `_render_template__600522146_80203160_0'
277
- /home/flyerhzm/Downloads/test_bullet/app/controllers/posts_controller.rb:7:in `index'
278
- </code></pre>
279
-
280
- The generated SQLs are
281
-
282
- <pre><code>
283
- Post Load (1.0ms) SELECT * FROM "posts"
284
- Comment Load (0.4ms) SELECT * FROM "comments" WHERE ("comments".post_id = 1)
285
- Comment Load (0.3ms) SELECT * FROM "comments" WHERE ("comments".post_id = 2)
286
- </code></pre>
287
-
288
-
289
- 9. fix the N+1 query, change <code>app/controllers/posts_controller.rb</code> file
290
-
291
- <pre><code>
292
- def index
293
- @posts = Post.includes(:comments)
294
-
295
- respond_to do |format|
296
- format.html # index.html.erb
297
- format.xml { render :xml => @posts }
298
- end
299
- end
300
- </code></pre>
301
-
302
- 10. refresh http://localhost:3000/posts page, no alert box and no log appended.
303
-
304
- The generated SQLs are
305
-
306
- <pre><code>
307
- Post Load (0.5ms) SELECT * FROM "posts"
308
- Comment Load (0.5ms) SELECT "comments".* FROM "comments" WHERE ("comments".post_id IN (1,2))
309
- </code></pre>
310
-
311
- a N+1 query fixed. Cool!
312
-
313
- 11. now simulate unused eager loading. Change <code>app/controllers/posts_controller.rb</code> and <code>app/views/posts/index.html.erb</code>
314
-
315
- <pre><code>
316
- def index
317
- @posts = Post.includes(:comments)
318
-
319
- respond_to do |format|
320
- format.html # index.html.erb
321
- format.xml { render :xml => @posts }
322
- end
323
- end
324
- </code></pre>
325
-
326
- <pre><code>
327
- <% @posts.each do |post| %>
328
- <tr>
329
- <td><%= post.name %></td>
330
- <td><%= link_to 'Show', post %></td>
331
- <td><%= link_to 'Edit', edit_post_path(post) %></td>
332
- <td><%= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete %></td>
333
- </tr>
334
- <% end %>
335
- </code></pre>
336
-
337
- 12. refresh http://localhost:3000/posts page, then you will see a popup alert box says
338
-
339
- <pre><code>
340
- The request has unused preload associations as follows:
341
- model: Post => associations: [comment]
342
- The request has N+1 queries as follows:
343
- None
344
- </code></pre>
345
-
346
- In the meanwhile, there's a log appended into <code>log/bullet.log</code> file
347
-
348
- <pre><code>
349
- 2009-08-25 21:13:22[INFO] Unused preload associations: PATH_INFO: /posts; model: Post => associations: [comments]·
350
- Remove from your finder: :include => [:comments]
351
- </code></pre>
352
-
353
- 13. simulate counter_cache. Change <code>app/controllers/posts_controller.rb</code> and <code>app/views/posts/index.html.erb</code>
354
-
355
- <pre><code>
356
- def index
357
- @posts = Post.all
358
-
359
- respond_to do |format|
360
- format.html # index.html.erb
361
- format.xml { render :xml => @posts }
362
- end
363
- end
364
- </code></pre>
365
-
366
- <pre><code>
367
- <% @posts.each do |post| %>
368
- <tr>
369
- <td><%= post.name %></td>
370
- <td><%= post.comments.size %></td>
371
- <td><%= link_to 'Show', post %></td>
372
- <td><%= link_to 'Edit', edit_post_path(post) %></td>
373
- <td><%= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete %></td>
374
- </tr>
375
- <% end %>
376
- </code></pre>
377
-
378
- 14. refresh http://localhost:3000/posts page, then you will see a popup alert box says
379
-
380
- <pre><code>
381
- Need counter cache
382
- Post => [:comments]
383
- </code></pre>
384
-
385
- In the meanwhile, there's a log appended into <code>log/bullet.log</code> file.
386
-
387
- <pre><code>
388
- 2009-09-11 10:07:10[INFO] Need Counter Cache
389
- Post => [:comments]
390
- </code></pre>
391
-
392
- ****************************************************************************
393
-
394
-
395
- Copyright (c) 2009 - 2012 Richard Huang (flyerhzm@gmail.com), released under the MIT license