bullet 5.9.0 → 7.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/workflows/main.yml +82 -0
- data/CHANGELOG.md +72 -0
- data/Gemfile.rails-4.0 +1 -1
- data/Gemfile.rails-4.1 +1 -1
- data/Gemfile.rails-4.2 +1 -1
- data/Gemfile.rails-5.0 +1 -1
- data/Gemfile.rails-5.1 +1 -1
- data/Gemfile.rails-5.2 +1 -1
- data/Gemfile.rails-6.0 +15 -0
- data/Gemfile.rails-6.1 +15 -0
- data/Gemfile.rails-7.0 +10 -0
- data/MIT-LICENSE +1 -1
- data/README.md +59 -33
- data/lib/bullet/active_job.rb +13 -0
- data/lib/bullet/active_record4.rb +9 -32
- data/lib/bullet/active_record41.rb +8 -27
- data/lib/bullet/active_record42.rb +9 -24
- data/lib/bullet/active_record5.rb +190 -179
- data/lib/bullet/active_record52.rb +184 -169
- data/lib/bullet/active_record60.rb +274 -0
- data/lib/bullet/active_record61.rb +274 -0
- data/lib/bullet/active_record70.rb +277 -0
- data/lib/bullet/bullet_xhr.js +64 -0
- data/lib/bullet/dependency.rb +60 -36
- data/lib/bullet/detector/association.rb +26 -20
- data/lib/bullet/detector/counter_cache.rb +15 -11
- data/lib/bullet/detector/n_plus_one_query.rb +24 -14
- data/lib/bullet/detector/unused_eager_loading.rb +8 -5
- data/lib/bullet/ext/object.rb +4 -2
- data/lib/bullet/mongoid4x.rb +3 -7
- data/lib/bullet/mongoid5x.rb +3 -7
- data/lib/bullet/mongoid6x.rb +3 -7
- data/lib/bullet/mongoid7x.rb +34 -23
- data/lib/bullet/notification/base.rb +14 -18
- data/lib/bullet/notification/n_plus_one_query.rb +2 -4
- data/lib/bullet/notification/unused_eager_loading.rb +2 -4
- data/lib/bullet/notification.rb +2 -1
- data/lib/bullet/rack.rb +55 -27
- data/lib/bullet/stack_trace_filter.rb +11 -19
- data/lib/bullet/version.rb +1 -1
- data/lib/bullet.rb +68 -42
- data/lib/generators/bullet/install_generator.rb +22 -23
- data/perf/benchmark.rb +11 -14
- data/spec/bullet/detector/counter_cache_spec.rb +6 -6
- data/spec/bullet/detector/n_plus_one_query_spec.rb +8 -4
- data/spec/bullet/detector/unused_eager_loading_spec.rb +25 -8
- data/spec/bullet/ext/object_spec.rb +10 -5
- data/spec/bullet/notification/base_spec.rb +5 -7
- data/spec/bullet/notification/n_plus_one_query_spec.rb +16 -3
- data/spec/bullet/notification/unused_eager_loading_spec.rb +5 -1
- data/spec/bullet/rack_spec.rb +161 -11
- data/spec/bullet/registry/association_spec.rb +2 -2
- data/spec/bullet/registry/base_spec.rb +1 -1
- data/spec/bullet_spec.rb +25 -44
- data/spec/integration/active_record/association_spec.rb +115 -144
- data/spec/integration/counter_cache_spec.rb +14 -34
- data/spec/integration/mongoid/association_spec.rb +19 -33
- data/spec/models/attachment.rb +5 -0
- data/spec/models/deal.rb +5 -0
- data/spec/models/post.rb +2 -0
- data/spec/models/role.rb +7 -0
- data/spec/models/submission.rb +1 -0
- data/spec/models/user.rb +2 -0
- data/spec/spec_helper.rb +4 -10
- data/spec/support/bullet_ext.rb +8 -9
- data/spec/support/mongo_seed.rb +3 -16
- data/spec/support/sqlite_seed.rb +38 -0
- data/test.sh +3 -0
- metadata +21 -8
- data/.travis.yml +0 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 1ee8344236feb882d0359202c851abb8887b6b3bb31186f2b37329a41fbc3e96
|
4
|
+
data.tar.gz: 9d1aea1b67a6777c56b2548e93614ee051d5799e8caf9ecb0d48663a6a7b5bd8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f603fb2540b20dd0e5d5e519de308b9a264d264bbea6db9d7399c25d6912e053aa243cb877b98cfa123f3eca9142bc0fec1bf9b4ff41f411efd6a895f616916b
|
7
|
+
data.tar.gz: 1e000b7bb96d2479108bb67bc6ac6d4efdc3f337f76f42e8227d1b8b9394a7d38d09df0104ceb3ed7b6e9a98b570dc0f32d3eeff85277490e4ee0c552b577f5b
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# This workflow uses actions that are not certified by GitHub.
|
2
|
+
# They are provided by a third-party and are governed by
|
3
|
+
# separate terms of service, privacy policy, and support
|
4
|
+
# documentation.
|
5
|
+
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
|
6
|
+
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
|
7
|
+
|
8
|
+
name: CI
|
9
|
+
|
10
|
+
on:
|
11
|
+
push:
|
12
|
+
branches: [ master ]
|
13
|
+
pull_request:
|
14
|
+
branches: [ master ]
|
15
|
+
|
16
|
+
jobs:
|
17
|
+
test_rails_4:
|
18
|
+
runs-on: ubuntu-latest
|
19
|
+
strategy:
|
20
|
+
matrix:
|
21
|
+
gemfile: ['Gemfile.rails-4.0', 'Gemfile.rails-4.1', 'Gemfile.rails-4.2']
|
22
|
+
env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps
|
23
|
+
BUNDLE_GEMFILE: ${{ github.workspace }}/${{ matrix.gemfile }}
|
24
|
+
steps:
|
25
|
+
- uses: actions/checkout@v2
|
26
|
+
- name: Set up Ruby
|
27
|
+
uses: ruby/setup-ruby@v1
|
28
|
+
with:
|
29
|
+
ruby-version: 2.3
|
30
|
+
bundler: 1
|
31
|
+
bundler-cache: true
|
32
|
+
- name: Run tests
|
33
|
+
run: bundle exec rake
|
34
|
+
test_rails_5:
|
35
|
+
runs-on: ubuntu-latest
|
36
|
+
strategy:
|
37
|
+
matrix:
|
38
|
+
gemfile: ['Gemfile.rails-5.0', 'Gemfile.rails-5.1', 'Gemfile.rails-5.2']
|
39
|
+
env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps
|
40
|
+
BUNDLE_GEMFILE: ${{ github.workspace }}/${{ matrix.gemfile }}
|
41
|
+
steps:
|
42
|
+
- uses: actions/checkout@v2
|
43
|
+
- name: Set up Ruby
|
44
|
+
uses: ruby/setup-ruby@v1
|
45
|
+
with:
|
46
|
+
ruby-version: 2.5
|
47
|
+
bundler: 1
|
48
|
+
bundler-cache: true
|
49
|
+
- name: Run tests
|
50
|
+
run: bundle exec rake
|
51
|
+
test_rails_6:
|
52
|
+
runs-on: ubuntu-latest
|
53
|
+
strategy:
|
54
|
+
matrix:
|
55
|
+
gemfile: ['Gemfile.rails-6.0', 'Gemfile.rails-6.1']
|
56
|
+
env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps
|
57
|
+
BUNDLE_GEMFILE: ${{ github.workspace }}/${{ matrix.gemfile }}
|
58
|
+
steps:
|
59
|
+
- uses: actions/checkout@v2
|
60
|
+
- name: Set up Ruby
|
61
|
+
uses: ruby/setup-ruby@v1
|
62
|
+
with:
|
63
|
+
ruby-version: 2.7
|
64
|
+
bundler-cache: true
|
65
|
+
- name: Run tests
|
66
|
+
run: bundle exec rake
|
67
|
+
test_rails_7:
|
68
|
+
runs-on: ubuntu-latest
|
69
|
+
strategy:
|
70
|
+
matrix:
|
71
|
+
gemfile: ['Gemfile.rails-7.0']
|
72
|
+
env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps
|
73
|
+
BUNDLE_GEMFILE: ${{ github.workspace }}/${{ matrix.gemfile }}
|
74
|
+
steps:
|
75
|
+
- uses: actions/checkout@v2
|
76
|
+
- name: Set up Ruby
|
77
|
+
uses: ruby/setup-ruby@v1
|
78
|
+
with:
|
79
|
+
ruby-version: 3.1
|
80
|
+
bundler-cache: true
|
81
|
+
- name: Run tests
|
82
|
+
run: bundle exec rake
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,77 @@
|
|
1
1
|
## Next Release
|
2
2
|
|
3
|
+
## 7.0.4 (11/28/2022)
|
4
|
+
|
5
|
+
* Fix `eager_load` `has_many :through` false positives
|
6
|
+
* mongoid7x: add dynamic methods
|
7
|
+
|
8
|
+
## 7.0.3 (08/13/2022)
|
9
|
+
|
10
|
+
* Replace `Array()` with `Array.wrap()`
|
11
|
+
|
12
|
+
## 7.0.2 (05/31/2022)
|
13
|
+
|
14
|
+
* Drop growl support
|
15
|
+
* Do not check html tag in Bullet::Rack anymore
|
16
|
+
|
17
|
+
## 7.0.1 (01/15/2022)
|
18
|
+
|
19
|
+
* Get rid of *_whitelist methods
|
20
|
+
* Hack ActiveRecord::Associations::Preloader::Batch in rails 7
|
21
|
+
|
22
|
+
## 7.0.0 (12/18/2021)
|
23
|
+
|
24
|
+
* Support rails 7
|
25
|
+
* Fix Mongoid 7 view iteration
|
26
|
+
* Move CI from Travis to Github Actions
|
27
|
+
|
28
|
+
## 6.1.5 (08/16/2021)
|
29
|
+
|
30
|
+
* Rename whitelist to safelist
|
31
|
+
* Fix onload called twice
|
32
|
+
* Support Rack::Files::Iterator responses
|
33
|
+
* Ensure HABTM associations are not incorrectly labeled n+1
|
34
|
+
|
35
|
+
## 6.1.4 (02/26/2021)
|
36
|
+
|
37
|
+
* Added an option to stop adding HTTP headers to API requests
|
38
|
+
|
39
|
+
## 6.1.3 (01/21/2021)
|
40
|
+
|
41
|
+
* Consider ThroughAssociation at SingularAssociation like CollectionAssociation
|
42
|
+
* Add xhr_script only when add_footer is enabled
|
43
|
+
|
44
|
+
## 6.1.2 (12/12/2020)
|
45
|
+
|
46
|
+
* Revert "Make whitelist thread safe"
|
47
|
+
|
48
|
+
## 6.1.1 (12/12/2020)
|
49
|
+
|
50
|
+
* Add support Rails 6.1
|
51
|
+
* Make whitelist thread safe
|
52
|
+
|
53
|
+
## 6.1.0 (12/28/2019)
|
54
|
+
|
55
|
+
* Add skip_html_injection flag
|
56
|
+
* Remove writer hack in active_record6
|
57
|
+
* Use modern includes syntax in warnings
|
58
|
+
* Fix warning: The last argument is used as the keyword parameter
|
59
|
+
|
60
|
+
## 6.0.2 (08/20/2019)
|
61
|
+
|
62
|
+
* Fully support Rails 6.0
|
63
|
+
|
64
|
+
## 6.0.1 (06/26/2019)
|
65
|
+
|
66
|
+
* Add Bullet::ActiveJob
|
67
|
+
* Prevent "Maximum call stack exceeded" errors when used with Turbolinks
|
68
|
+
|
69
|
+
## 6.0.0 (04/25/2019)
|
70
|
+
|
71
|
+
* Add XHR support to Bullet
|
72
|
+
* Support Rails 6.0
|
73
|
+
* Handle case where ID is manually set on unpersisted record
|
74
|
+
|
3
75
|
## 5.9.0 (11/11/2018)
|
4
76
|
|
5
77
|
* Require Ruby 2.3+
|
data/Gemfile.rails-4.0
CHANGED
@@ -3,7 +3,7 @@ source "https://rubygems.org"
|
|
3
3
|
gemspec
|
4
4
|
|
5
5
|
gem 'rails', '~> 4.0.0'
|
6
|
-
gem 'sqlite3', platforms: [:ruby]
|
6
|
+
gem 'sqlite3', '~> 1.3.6', platforms: [:ruby]
|
7
7
|
gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
|
8
8
|
gem 'activerecord-import'
|
9
9
|
gem 'tins', '~> 1.6.0', platforms: [:ruby_19]
|
data/Gemfile.rails-4.1
CHANGED
data/Gemfile.rails-4.2
CHANGED
data/Gemfile.rails-5.0
CHANGED
data/Gemfile.rails-5.1
CHANGED
data/Gemfile.rails-5.2
CHANGED
data/Gemfile.rails-6.0
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
source "https://rubygems.org"
|
2
|
+
|
3
|
+
gemspec
|
4
|
+
|
5
|
+
gem 'rails', '~> 6.0.0'
|
6
|
+
gem 'sqlite3'
|
7
|
+
gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
|
8
|
+
gem 'activerecord-import'
|
9
|
+
|
10
|
+
gem "rspec"
|
11
|
+
|
12
|
+
platforms :rbx do
|
13
|
+
gem 'rubysl', '~> 2.0'
|
14
|
+
gem 'rubinius-developer_tools'
|
15
|
+
end
|
data/Gemfile.rails-6.1
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
source "https://rubygems.org"
|
2
|
+
|
3
|
+
gemspec
|
4
|
+
|
5
|
+
gem 'rails', '~> 6.1.0'
|
6
|
+
gem 'sqlite3'
|
7
|
+
gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
|
8
|
+
gem 'activerecord-import'
|
9
|
+
|
10
|
+
gem "rspec"
|
11
|
+
|
12
|
+
platforms :rbx do
|
13
|
+
gem 'rubysl', '~> 2.0'
|
14
|
+
gem 'rubinius-developer_tools'
|
15
|
+
end
|
data/Gemfile.rails-7.0
ADDED
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# Bullet
|
2
2
|
|
3
|
-
|
4
|
-
[![
|
3
|
+
![Main workflow](https://github.com/flyerhzm/bullet/actions/workflows/main.yml/badge.svg)
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/bullet.svg)](http://badge.fury.io/rb/bullet)
|
5
5
|
[![AwesomeCode Status for flyerhzm/bullet](https://awesomecode.io/projects/6755235b-e2c1-459e-bf92-b8b13d0c0472/status)](https://awesomecode.io/repos/flyerhzm/bullet)
|
6
6
|
[![Coderwall Endorse](http://api.coderwall.com/flyerhzm/endorsecount.png)](http://coderwall.com/flyerhzm)
|
7
7
|
|
@@ -37,12 +37,19 @@ or add it into a Gemfile (Bundler):
|
|
37
37
|
gem 'bullet', group: 'development'
|
38
38
|
```
|
39
39
|
|
40
|
+
enable the Bullet gem with generate command
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
bundle exec rails g bullet:install
|
44
|
+
```
|
45
|
+
The generate command will auto generate the default configuration and may ask to include in the test environment as well. See below for custom configuration.
|
46
|
+
|
40
47
|
**Note**: make sure `bullet` gem is added after activerecord (rails) and
|
41
48
|
mongoid.
|
42
49
|
|
43
50
|
## Configuration
|
44
51
|
|
45
|
-
Bullet won't
|
52
|
+
Bullet won't enable any notification systems unless you tell it to explicitly. Append to
|
46
53
|
`config/environments/development.rb` initializer with the following code:
|
47
54
|
|
48
55
|
```ruby
|
@@ -52,7 +59,6 @@ config.after_initialize do
|
|
52
59
|
Bullet.alert = true
|
53
60
|
Bullet.bullet_logger = true
|
54
61
|
Bullet.console = true
|
55
|
-
Bullet.growl = true
|
56
62
|
Bullet.xmpp = { :account => 'bullets_account@jabber.org',
|
57
63
|
:password => 'bullets_password_for_jabber',
|
58
64
|
:receiver => 'your_account@jabber.org',
|
@@ -60,9 +66,11 @@ config.after_initialize do
|
|
60
66
|
Bullet.rails_logger = true
|
61
67
|
Bullet.honeybadger = true
|
62
68
|
Bullet.bugsnag = true
|
69
|
+
Bullet.appsignal = true
|
63
70
|
Bullet.airbrake = true
|
64
71
|
Bullet.rollbar = true
|
65
72
|
Bullet.add_footer = true
|
73
|
+
Bullet.skip_html_injection = false
|
66
74
|
Bullet.stacktrace_includes = [ 'your_gem', 'your_middleware' ]
|
67
75
|
Bullet.stacktrace_excludes = [ 'their_gem', 'their_middleware', ['my_file.rb', 'my_method'], ['my_file.rb', 16..20] ]
|
68
76
|
Bullet.slack = { webhook_url: 'http://some.slack.url', channel: '#default', username: 'notifier' }
|
@@ -76,15 +84,17 @@ The code above will enable all of the Bullet notification systems:
|
|
76
84
|
* `Bullet.alert`: pop up a JavaScript alert in the browser
|
77
85
|
* `Bullet.bullet_logger`: log to the Bullet log file (Rails.root/log/bullet.log)
|
78
86
|
* `Bullet.console`: log warnings to your browser's console.log (Safari/Webkit browsers or Firefox w/Firebug installed)
|
79
|
-
* `Bullet.growl`: pop up Growl warnings if your system has Growl installed. Requires a little bit of configuration
|
80
87
|
* `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.
|
81
88
|
* `Bullet.rails_logger`: add warnings directly to the Rails log
|
82
89
|
* `Bullet.honeybadger`: add notifications to Honeybadger
|
83
90
|
* `Bullet.bugsnag`: add notifications to bugsnag
|
84
91
|
* `Bullet.airbrake`: add notifications to airbrake
|
92
|
+
* `Bullet.appsignal`: add notifications to AppSignal
|
85
93
|
* `Bullet.rollbar`: add notifications to rollbar
|
86
94
|
* `Bullet.sentry`: add notifications to sentry
|
87
95
|
* `Bullet.add_footer`: adds the details in the bottom left corner of the page. Double click the footer or use close button to hide footer.
|
96
|
+
* `Bullet.skip_html_injection`: prevents Bullet from injecting code into the returned HTML. This must be false for receiving alerts, showing the footer or console logging.
|
97
|
+
* `Bullet.skip_http_headers`: don't add headers to API requests, and remove the javascript that relies on them. Note that this prevents bullet from logging warnings to the browser console or updating the footer.
|
88
98
|
* `Bullet.stacktrace_includes`: include paths with any of these substrings in the stack trace, even if they are not in your main app
|
89
99
|
* `Bullet.stacktrace_excludes`: ignore paths with any of these substrings in the stack trace, even if they are not in your main app.
|
90
100
|
Each item can be a string (match substring), a regex, or an array where the first item is a path to match, and the second
|
@@ -109,15 +119,15 @@ Bullet.unused_eager_loading_enable = false
|
|
109
119
|
Bullet.counter_cache_enable = false
|
110
120
|
```
|
111
121
|
|
112
|
-
##
|
122
|
+
## Safe list
|
113
123
|
|
114
124
|
Sometimes Bullet may notify you of query problems you don't care to fix, or
|
115
|
-
which come from outside your code. You can
|
125
|
+
which come from outside your code. You can add them to a safe list to ignore them:
|
116
126
|
|
117
127
|
```ruby
|
118
|
-
Bullet.
|
119
|
-
Bullet.
|
120
|
-
Bullet.
|
128
|
+
Bullet.add_safelist :type => :n_plus_one_query, :class_name => "Post", :association => :comments
|
129
|
+
Bullet.add_safelist :type => :unused_eager_loading, :class_name => "Post", :association => :comments
|
130
|
+
Bullet.add_safelist :type => :counter_cache, :class_name => "Country", :association => :cities
|
121
131
|
```
|
122
132
|
|
123
133
|
If you want to skip bullet in some specific controller actions, you can
|
@@ -125,7 +135,7 @@ do like
|
|
125
135
|
|
126
136
|
```ruby
|
127
137
|
class ApplicationController < ActionController::Base
|
128
|
-
around_action :skip_bullet
|
138
|
+
around_action :skip_bullet, if: -> { defined?(Bullet) }
|
129
139
|
|
130
140
|
def skip_bullet
|
131
141
|
previous_value = Bullet.enable?
|
@@ -144,25 +154,26 @@ The Bullet log `log/bullet.log` will look something like this:
|
|
144
154
|
* N+1 Query:
|
145
155
|
|
146
156
|
```
|
147
|
-
2009-08-25 20:40:17[INFO]
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
/Users/richard/Downloads/test/app/views/posts/index.html.erb:8:in `each'
|
152
|
-
/Users/richard/Downloads/test/app/
|
153
|
-
/Users/richard/Downloads/test/app/controllers/posts_controller.rb:7:in `index'
|
157
|
+
2009-08-25 20:40:17[INFO] USE eager loading detected:
|
158
|
+
Post => [:comments]·
|
159
|
+
Add to your query: .includes([:comments])
|
160
|
+
2009-08-25 20:40:17[INFO] Call stack
|
161
|
+
/Users/richard/Downloads/test/app/views/posts/index.html.erb:8:in `each'
|
162
|
+
/Users/richard/Downloads/test/app/controllers/posts_controller.rb:7:in `index'
|
154
163
|
```
|
155
164
|
|
156
|
-
The first
|
165
|
+
The first log entry is a notification that N+1 queries have been encountered. The remaining entry is a stack trace so you can find exactly where the queries were invoked in your code, and fix them.
|
157
166
|
|
158
167
|
* Unused eager loading:
|
159
168
|
|
160
169
|
```
|
161
|
-
2009-08-25 20:53:56[INFO]
|
162
|
-
|
170
|
+
2009-08-25 20:53:56[INFO] AVOID eager loading detected
|
171
|
+
Post => [:comments]·
|
172
|
+
Remove from your query: .includes([:comments])
|
173
|
+
2009-08-25 20:53:56[INFO] Call stack
|
163
174
|
```
|
164
175
|
|
165
|
-
These
|
176
|
+
These lines are notifications that unused eager loadings have been encountered.
|
166
177
|
|
167
178
|
* Need counter cache:
|
168
179
|
|
@@ -171,25 +182,41 @@ These two lines are notifications that unused eager loadings have been encounter
|
|
171
182
|
Post => [:comments]
|
172
183
|
```
|
173
184
|
|
174
|
-
##
|
185
|
+
## XMPP/Jabber and Airbrake Support
|
175
186
|
|
176
187
|
see [https://github.com/flyerhzm/uniform_notifier](https://github.com/flyerhzm/uniform_notifier)
|
177
188
|
|
189
|
+
## Growl Support
|
190
|
+
|
191
|
+
Growl support is dropped from uniform_notifier 1.16.0, if you still want it, please use uniform_notifier 1.15.0.
|
192
|
+
|
178
193
|
## Important
|
179
194
|
|
180
195
|
If you find Bullet does not work for you, *please disable your browser's cache*.
|
181
196
|
|
182
197
|
## Advanced
|
183
198
|
|
184
|
-
###
|
199
|
+
### Work with ActiveJob
|
185
200
|
|
186
|
-
|
201
|
+
Include `Bullet::ActiveJob` in your `ApplicationJob`.
|
187
202
|
|
188
203
|
```ruby
|
189
|
-
|
190
|
-
|
204
|
+
class ApplicationJob < ActiveJob::Base
|
205
|
+
include Bullet::ActiveJob if Rails.env.development?
|
206
|
+
end
|
207
|
+
```
|
208
|
+
|
209
|
+
### Work with other background job solution
|
191
210
|
|
192
|
-
|
211
|
+
Use the Bullet.profile method.
|
212
|
+
|
213
|
+
```ruby
|
214
|
+
class ApplicationJob < ActiveJob::Base
|
215
|
+
around_perform do |_job, block|
|
216
|
+
Bullet.profile do
|
217
|
+
block.call
|
218
|
+
end
|
219
|
+
end
|
193
220
|
end
|
194
221
|
```
|
195
222
|
|
@@ -221,7 +248,7 @@ end
|
|
221
248
|
Then wrap each test in Bullet api.
|
222
249
|
|
223
250
|
```ruby
|
224
|
-
# spec/
|
251
|
+
# spec/rails_helper.rb
|
225
252
|
if Bullet.enable?
|
226
253
|
config.before(:each) do
|
227
254
|
Bullet.start_request
|
@@ -246,8 +273,7 @@ Bullet outputs some details info, to enable debug mode, set
|
|
246
273
|
## Demo
|
247
274
|
|
248
275
|
Bullet is designed to function as you browse through your application in development. To see it in action,
|
249
|
-
you can
|
250
|
-
follow these steps to create, detect, and fix example query problems.
|
276
|
+
you can follow these steps to create, detect, and fix example query problems.
|
251
277
|
|
252
278
|
1\. Create an example application
|
253
279
|
|
@@ -259,7 +285,7 @@ $ rails g scaffold comment name:string post_id:integer
|
|
259
285
|
$ bundle exec rake db:migrate
|
260
286
|
```
|
261
287
|
|
262
|
-
2\. Change `app/
|
288
|
+
2\. Change `app/models/post.rb` and `app/models/comment.rb`
|
263
289
|
|
264
290
|
```ruby
|
265
291
|
class Post < ActiveRecord::Base
|
@@ -458,4 +484,4 @@ Meanwhile, there's a line appended to `log/bullet.log`
|
|
458
484
|
Post => [:comments]
|
459
485
|
```
|
460
486
|
|
461
|
-
Copyright (c) 2009 -
|
487
|
+
Copyright (c) 2009 - 2022 Richard Huang (flyerhzm@gmail.com), released under the MIT license
|
@@ -5,7 +5,7 @@ module Bullet
|
|
5
5
|
def self.enable
|
6
6
|
require 'active_record'
|
7
7
|
::ActiveRecord::Base.class_eval do
|
8
|
-
class <<self
|
8
|
+
class << self
|
9
9
|
alias_method :origin_find_by_sql, :find_by_sql
|
10
10
|
def find_by_sql(sql, binds = [])
|
11
11
|
result = origin_find_by_sql(sql, binds)
|
@@ -49,9 +49,7 @@ module Bullet
|
|
49
49
|
|
50
50
|
::ActiveRecord::Persistence.class_eval do
|
51
51
|
def _create_record_with_bullet(*args)
|
52
|
-
_create_record_without_bullet(*args).tap
|
53
|
-
Bullet::Detector::NPlusOneQuery.add_impossible_object(self)
|
54
|
-
end
|
52
|
+
_create_record_without_bullet(*args).tap { Bullet::Detector::NPlusOneQuery.add_impossible_object(self) }
|
55
53
|
end
|
56
54
|
alias_method_chain :_create_record, :bullet
|
57
55
|
end
|
@@ -62,13 +60,12 @@ module Bullet
|
|
62
60
|
alias_method :origin_initialize, :initialize
|
63
61
|
def initialize(records, associations, preload_scope = nil)
|
64
62
|
origin_initialize(records, associations, preload_scope)
|
63
|
+
|
65
64
|
if Bullet.start?
|
66
65
|
records = [records].flatten.compact.uniq
|
67
66
|
return if records.empty?
|
68
67
|
|
69
|
-
records.each
|
70
|
-
Bullet::Detector::Association.add_object_associations(record, associations)
|
71
|
-
end
|
68
|
+
records.each { |record| Bullet::Detector::Association.add_object_associations(record, associations) }
|
72
69
|
Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, associations)
|
73
70
|
end
|
74
71
|
end
|
@@ -81,9 +78,7 @@ module Bullet
|
|
81
78
|
records = origin_find_with_associations
|
82
79
|
if Bullet.start?
|
83
80
|
associations = (eager_load_values + includes_values).uniq
|
84
|
-
records.each
|
85
|
-
Bullet::Detector::Association.add_object_associations(record, associations)
|
86
|
-
end
|
81
|
+
records.each { |record| Bullet::Detector::Association.add_object_associations(record, associations) }
|
87
82
|
Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, associations)
|
88
83
|
end
|
89
84
|
records
|
@@ -128,17 +123,13 @@ module Bullet
|
|
128
123
|
# call one to many associations
|
129
124
|
alias_method :origin_load_target, :load_target
|
130
125
|
def load_target
|
131
|
-
if Bullet.start?
|
132
|
-
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
133
|
-
end
|
126
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name) if Bullet.start?
|
134
127
|
origin_load_target
|
135
128
|
end
|
136
129
|
|
137
130
|
alias_method :origin_include?, :include?
|
138
131
|
def include?(object)
|
139
|
-
if Bullet.start?
|
140
|
-
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
141
|
-
end
|
132
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name) if Bullet.start?
|
142
133
|
origin_include?(object)
|
143
134
|
end
|
144
135
|
end
|
@@ -156,9 +147,7 @@ module Bullet
|
|
156
147
|
::ActiveRecord::Associations::HasAndBelongsToManyAssociation.class_eval do
|
157
148
|
alias_method :origin_empty?, :empty?
|
158
149
|
def empty?
|
159
|
-
if Bullet.start? && !loaded?
|
160
|
-
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
161
|
-
end
|
150
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name) if Bullet.start? && !loaded?
|
162
151
|
origin_empty?
|
163
152
|
end
|
164
153
|
end
|
@@ -181,23 +170,11 @@ module Bullet
|
|
181
170
|
::ActiveRecord::Associations::HasManyAssociation.class_eval do
|
182
171
|
alias_method :origin_has_cached_counter?, :has_cached_counter?
|
183
172
|
|
184
|
-
# rubocop:disable Style/MethodCallWithoutArgsParentheses
|
185
173
|
def has_cached_counter?(reflection = reflection())
|
186
174
|
result = origin_has_cached_counter?(reflection)
|
187
|
-
if Bullet.start? && !result
|
188
|
-
Bullet::Detector::CounterCache.add_counter_cache(owner, reflection.name)
|
189
|
-
end
|
175
|
+
Bullet::Detector::CounterCache.add_counter_cache(owner, reflection.name) if Bullet.start? && !result
|
190
176
|
result
|
191
177
|
end
|
192
|
-
# rubocop:enable Style/MethodCallWithoutArgsParentheses
|
193
|
-
end
|
194
|
-
|
195
|
-
::ActiveRecord::Associations::BelongsToAssociation.class_eval do
|
196
|
-
def writer_with_bullet(record)
|
197
|
-
Bullet::Detector::Association.add_object_associations(owner, reflection.name) if Bullet.start?
|
198
|
-
writer_without_bullet(record)
|
199
|
-
end
|
200
|
-
alias_method_chain :writer, :bullet
|
201
178
|
end
|
202
179
|
end
|
203
180
|
end
|