bullet 6.1.3 → 7.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +82 -0
- data/CHANGELOG.md +36 -0
- data/Gemfile.rails-7.0 +10 -0
- data/MIT-LICENSE +1 -1
- data/README.md +31 -26
- data/lib/bullet/active_record41.rb +1 -0
- data/lib/bullet/active_record42.rb +1 -0
- data/lib/bullet/active_record5.rb +6 -4
- data/lib/bullet/active_record52.rb +18 -22
- data/lib/bullet/active_record60.rb +17 -21
- data/lib/bullet/active_record61.rb +17 -21
- data/lib/bullet/active_record70.rb +277 -0
- data/lib/bullet/bullet_xhr.js +3 -2
- data/lib/bullet/dependency.rb +10 -0
- data/lib/bullet/detector/base.rb +2 -1
- data/lib/bullet/detector/counter_cache.rb +2 -2
- data/lib/bullet/detector/n_plus_one_query.rb +5 -5
- data/lib/bullet/detector/unused_eager_loading.rb +2 -2
- data/lib/bullet/mongoid7x.rb +34 -19
- data/lib/bullet/notification.rb +2 -1
- data/lib/bullet/rack.rb +7 -4
- data/lib/bullet/stack_trace_filter.rb +7 -8
- data/lib/bullet/version.rb +1 -1
- data/lib/bullet.rb +23 -24
- data/lib/generators/bullet/install_generator.rb +0 -1
- data/perf/benchmark.rb +4 -1
- data/spec/bullet/detector/n_plus_one_query_spec.rb +1 -1
- data/spec/bullet/detector/unused_eager_loading_spec.rb +6 -2
- data/spec/bullet/ext/object_spec.rb +1 -1
- data/spec/bullet/notification/base_spec.rb +4 -4
- data/spec/bullet/rack_spec.rb +90 -19
- data/spec/bullet_spec.rb +15 -15
- data/spec/integration/active_record/association_spec.rb +36 -9
- data/spec/integration/counter_cache_spec.rb +4 -4
- data/spec/integration/mongoid/association_spec.rb +1 -1
- data/spec/models/deal.rb +5 -0
- data/spec/models/folder.rb +2 -1
- data/spec/models/group.rb +2 -1
- data/spec/models/page.rb +2 -1
- data/spec/models/post.rb +2 -0
- data/spec/models/role.rb +7 -0
- data/spec/models/user.rb +1 -0
- data/spec/models/writer.rb +2 -1
- data/spec/spec_helper.rb +0 -2
- data/spec/support/mongo_seed.rb +1 -0
- data/spec/support/sqlite_seed.rb +30 -0
- data/test.sh +2 -0
- metadata +10 -4
- data/.travis.yml +0 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
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,41 @@
|
|
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
|
+
|
3
39
|
## 6.1.3 (01/21/2021)
|
4
40
|
|
5
41
|
* Consider ThroughAssociation at SingularAssociation like CollectionAssociation
|
data/Gemfile.rails-7.0
ADDED
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# Bullet
|
2
2
|
|
3
|
+
![Main workflow](https://github.com/flyerhzm/bullet/actions/workflows/main.yml/badge.svg)
|
3
4
|
[![Gem Version](https://badge.fury.io/rb/bullet.svg)](http://badge.fury.io/rb/bullet)
|
4
|
-
[![Build Status](https://secure.travis-ci.org/flyerhzm/bullet.svg)](http://travis-ci.org/flyerhzm/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
|
|
@@ -49,7 +49,7 @@ mongoid.
|
|
49
49
|
|
50
50
|
## Configuration
|
51
51
|
|
52
|
-
Bullet won't
|
52
|
+
Bullet won't enable any notification systems unless you tell it to explicitly. Append to
|
53
53
|
`config/environments/development.rb` initializer with the following code:
|
54
54
|
|
55
55
|
```ruby
|
@@ -59,7 +59,6 @@ config.after_initialize do
|
|
59
59
|
Bullet.alert = true
|
60
60
|
Bullet.bullet_logger = true
|
61
61
|
Bullet.console = true
|
62
|
-
Bullet.growl = true
|
63
62
|
Bullet.xmpp = { :account => 'bullets_account@jabber.org',
|
64
63
|
:password => 'bullets_password_for_jabber',
|
65
64
|
:receiver => 'your_account@jabber.org',
|
@@ -67,6 +66,7 @@ config.after_initialize do
|
|
67
66
|
Bullet.rails_logger = true
|
68
67
|
Bullet.honeybadger = true
|
69
68
|
Bullet.bugsnag = true
|
69
|
+
Bullet.appsignal = true
|
70
70
|
Bullet.airbrake = true
|
71
71
|
Bullet.rollbar = true
|
72
72
|
Bullet.add_footer = true
|
@@ -84,16 +84,17 @@ The code above will enable all of the Bullet notification systems:
|
|
84
84
|
* `Bullet.alert`: pop up a JavaScript alert in the browser
|
85
85
|
* `Bullet.bullet_logger`: log to the Bullet log file (Rails.root/log/bullet.log)
|
86
86
|
* `Bullet.console`: log warnings to your browser's console.log (Safari/Webkit browsers or Firefox w/Firebug installed)
|
87
|
-
* `Bullet.growl`: pop up Growl warnings if your system has Growl installed. Requires a little bit of configuration
|
88
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.
|
89
88
|
* `Bullet.rails_logger`: add warnings directly to the Rails log
|
90
89
|
* `Bullet.honeybadger`: add notifications to Honeybadger
|
91
90
|
* `Bullet.bugsnag`: add notifications to bugsnag
|
92
91
|
* `Bullet.airbrake`: add notifications to airbrake
|
92
|
+
* `Bullet.appsignal`: add notifications to AppSignal
|
93
93
|
* `Bullet.rollbar`: add notifications to rollbar
|
94
94
|
* `Bullet.sentry`: add notifications to sentry
|
95
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
|
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.
|
97
98
|
* `Bullet.stacktrace_includes`: include paths with any of these substrings in the stack trace, even if they are not in your main app
|
98
99
|
* `Bullet.stacktrace_excludes`: ignore paths with any of these substrings in the stack trace, even if they are not in your main app.
|
99
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
|
@@ -118,15 +119,15 @@ Bullet.unused_eager_loading_enable = false
|
|
118
119
|
Bullet.counter_cache_enable = false
|
119
120
|
```
|
120
121
|
|
121
|
-
##
|
122
|
+
## Safe list
|
122
123
|
|
123
124
|
Sometimes Bullet may notify you of query problems you don't care to fix, or
|
124
|
-
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:
|
125
126
|
|
126
127
|
```ruby
|
127
|
-
Bullet.
|
128
|
-
Bullet.
|
129
|
-
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
|
130
131
|
```
|
131
132
|
|
132
133
|
If you want to skip bullet in some specific controller actions, you can
|
@@ -153,25 +154,26 @@ The Bullet log `log/bullet.log` will look something like this:
|
|
153
154
|
* N+1 Query:
|
154
155
|
|
155
156
|
```
|
156
|
-
2009-08-25 20:40:17[INFO]
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
/Users/richard/Downloads/test/app/views/posts/index.html.erb:8:in `each'
|
161
|
-
/Users/richard/Downloads/test/app/
|
162
|
-
/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'
|
163
163
|
```
|
164
164
|
|
165
|
-
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.
|
166
166
|
|
167
167
|
* Unused eager loading:
|
168
168
|
|
169
169
|
```
|
170
|
-
2009-08-25 20:53:56[INFO]
|
171
|
-
|
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
|
172
174
|
```
|
173
175
|
|
174
|
-
These
|
176
|
+
These lines are notifications that unused eager loadings have been encountered.
|
175
177
|
|
176
178
|
* Need counter cache:
|
177
179
|
|
@@ -180,10 +182,14 @@ These two lines are notifications that unused eager loadings have been encounter
|
|
180
182
|
Post => [:comments]
|
181
183
|
```
|
182
184
|
|
183
|
-
##
|
185
|
+
## XMPP/Jabber and Airbrake Support
|
184
186
|
|
185
187
|
see [https://github.com/flyerhzm/uniform_notifier](https://github.com/flyerhzm/uniform_notifier)
|
186
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
|
+
|
187
193
|
## Important
|
188
194
|
|
189
195
|
If you find Bullet does not work for you, *please disable your browser's cache*.
|
@@ -267,8 +273,7 @@ Bullet outputs some details info, to enable debug mode, set
|
|
267
273
|
## Demo
|
268
274
|
|
269
275
|
Bullet is designed to function as you browse through your application in development. To see it in action,
|
270
|
-
you can
|
271
|
-
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.
|
272
277
|
|
273
278
|
1\. Create an example application
|
274
279
|
|
@@ -280,7 +285,7 @@ $ rails g scaffold comment name:string post_id:integer
|
|
280
285
|
$ bundle exec rake db:migrate
|
281
286
|
```
|
282
287
|
|
283
|
-
2\. Change `app/
|
288
|
+
2\. Change `app/models/post.rb` and `app/models/comment.rb`
|
284
289
|
|
285
290
|
```ruby
|
286
291
|
class Post < ActiveRecord::Base
|
@@ -479,4 +484,4 @@ Meanwhile, there's a line appended to `log/bullet.log`
|
|
479
484
|
Post => [:comments]
|
480
485
|
```
|
481
486
|
|
482
|
-
Copyright (c) 2009 -
|
487
|
+
Copyright (c) 2009 - 2022 Richard Huang (flyerhzm@gmail.com), released under the MIT license
|
@@ -30,6 +30,7 @@ module Bullet
|
|
30
30
|
|
31
31
|
::ActiveRecord::Relation.class_eval do
|
32
32
|
alias_method :origin_to_a, :to_a
|
33
|
+
|
33
34
|
# if select a collection of objects, then these objects have possible to cause N+1 query.
|
34
35
|
# if select only one object, then the only one object has impossible to cause N+1 query.
|
35
36
|
def to_a
|
@@ -52,6 +52,7 @@ module Bullet
|
|
52
52
|
|
53
53
|
::ActiveRecord::Relation.class_eval do
|
54
54
|
alias_method :origin_to_a, :to_a
|
55
|
+
|
55
56
|
# if select a collection of objects, then these objects have possible to cause N+1 query.
|
56
57
|
# if select only one object, then the only one object has impossible to cause N+1 query.
|
57
58
|
def to_a
|
@@ -177,10 +177,12 @@ module Bullet
|
|
177
177
|
if Bullet.start?
|
178
178
|
if is_a? ::ActiveRecord::Associations::ThroughAssociation
|
179
179
|
refl = reflection.through_reflection
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
180
|
+
association = owner.association(refl.name)
|
181
|
+
if association.loaded?
|
182
|
+
Bullet::Detector::NPlusOneQuery.call_association(owner, refl.name)
|
183
|
+
Array.wrap(association.target).each do |through_record|
|
184
|
+
Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
|
185
|
+
end
|
184
186
|
end
|
185
187
|
|
186
188
|
if refl.through_reflection?
|
@@ -75,23 +75,6 @@ module Bullet
|
|
75
75
|
end
|
76
76
|
)
|
77
77
|
|
78
|
-
::ActiveRecord::FinderMethods.prepend(
|
79
|
-
Module.new do
|
80
|
-
# add includes in scope
|
81
|
-
def find_with_associations
|
82
|
-
return super { |r| yield r } if block_given?
|
83
|
-
|
84
|
-
records = super
|
85
|
-
if Bullet.start?
|
86
|
-
associations = (eager_load_values + includes_values).uniq
|
87
|
-
records.each { |record| Bullet::Detector::Association.add_object_associations(record, associations) }
|
88
|
-
Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, associations)
|
89
|
-
end
|
90
|
-
records
|
91
|
-
end
|
92
|
-
end
|
93
|
-
)
|
94
|
-
|
95
78
|
::ActiveRecord::Associations::JoinDependency.prepend(
|
96
79
|
Module.new do
|
97
80
|
def instantiate(result_set, &block)
|
@@ -149,6 +132,17 @@ module Bullet
|
|
149
132
|
end
|
150
133
|
)
|
151
134
|
|
135
|
+
::ActiveRecord::Associations::Association.prepend(
|
136
|
+
Module.new do
|
137
|
+
def inversed_from(record)
|
138
|
+
if Bullet.start?
|
139
|
+
Bullet::Detector::NPlusOneQuery.add_inversed_object(owner, reflection.name)
|
140
|
+
end
|
141
|
+
super
|
142
|
+
end
|
143
|
+
end
|
144
|
+
)
|
145
|
+
|
152
146
|
::ActiveRecord::Associations::CollectionAssociation.prepend(
|
153
147
|
Module.new do
|
154
148
|
def load_target
|
@@ -156,10 +150,12 @@ module Bullet
|
|
156
150
|
|
157
151
|
if Bullet.start?
|
158
152
|
if is_a? ::ActiveRecord::Associations::ThroughAssociation
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
153
|
+
association = owner.association(reflection.through_reflection.name)
|
154
|
+
if association.loaded?
|
155
|
+
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
|
156
|
+
Array.wrap(association.target).each do |through_record|
|
157
|
+
Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
|
158
|
+
end
|
163
159
|
end
|
164
160
|
|
165
161
|
if reflection.through_reflection != through_reflection
|
@@ -205,7 +201,7 @@ module Bullet
|
|
205
201
|
if is_a? ::ActiveRecord::Associations::ThroughAssociation
|
206
202
|
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
|
207
203
|
association = owner.association reflection.through_reflection.name
|
208
|
-
Array(association.target).each do |through_record|
|
204
|
+
Array.wrap(association.target).each do |through_record|
|
209
205
|
Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
|
210
206
|
end
|
211
207
|
|
@@ -102,23 +102,6 @@ module Bullet
|
|
102
102
|
end
|
103
103
|
)
|
104
104
|
|
105
|
-
::ActiveRecord::FinderMethods.prepend(
|
106
|
-
Module.new do
|
107
|
-
# add includes in scope
|
108
|
-
def find_with_associations
|
109
|
-
return super { |r| yield r } if block_given?
|
110
|
-
|
111
|
-
records = super
|
112
|
-
if Bullet.start?
|
113
|
-
associations = (eager_load_values + includes_values).uniq
|
114
|
-
records.each { |record| Bullet::Detector::Association.add_object_associations(record, associations) }
|
115
|
-
Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, associations)
|
116
|
-
end
|
117
|
-
records
|
118
|
-
end
|
119
|
-
end
|
120
|
-
)
|
121
|
-
|
122
105
|
::ActiveRecord::Associations::JoinDependency.prepend(
|
123
106
|
Module.new do
|
124
107
|
def instantiate(result_set, &block)
|
@@ -176,6 +159,17 @@ module Bullet
|
|
176
159
|
end
|
177
160
|
)
|
178
161
|
|
162
|
+
::ActiveRecord::Associations::Association.prepend(
|
163
|
+
Module.new do
|
164
|
+
def inversed_from(record)
|
165
|
+
if Bullet.start?
|
166
|
+
Bullet::Detector::NPlusOneQuery.add_inversed_object(owner, reflection.name)
|
167
|
+
end
|
168
|
+
super
|
169
|
+
end
|
170
|
+
end
|
171
|
+
)
|
172
|
+
|
179
173
|
::ActiveRecord::Associations::CollectionAssociation.prepend(
|
180
174
|
Module.new do
|
181
175
|
def load_target
|
@@ -183,10 +177,12 @@ module Bullet
|
|
183
177
|
|
184
178
|
if Bullet.start?
|
185
179
|
if is_a? ::ActiveRecord::Associations::ThroughAssociation
|
186
|
-
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
|
187
180
|
association = owner.association(reflection.through_reflection.name)
|
188
|
-
|
189
|
-
Bullet::Detector::NPlusOneQuery.call_association(
|
181
|
+
if association.loaded?
|
182
|
+
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
|
183
|
+
Array.wrap(association.target).each do |through_record|
|
184
|
+
Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
|
185
|
+
end
|
190
186
|
end
|
191
187
|
|
192
188
|
if reflection.through_reflection != through_reflection
|
@@ -232,7 +228,7 @@ module Bullet
|
|
232
228
|
if is_a? ::ActiveRecord::Associations::ThroughAssociation
|
233
229
|
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
|
234
230
|
association = owner.association(reflection.through_reflection.name)
|
235
|
-
Array(association.target).each do |through_record|
|
231
|
+
Array.wrap(association.target).each do |through_record|
|
236
232
|
Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
|
237
233
|
end
|
238
234
|
|
@@ -102,23 +102,6 @@ module Bullet
|
|
102
102
|
end
|
103
103
|
)
|
104
104
|
|
105
|
-
::ActiveRecord::FinderMethods.prepend(
|
106
|
-
Module.new do
|
107
|
-
# add includes in scope
|
108
|
-
def find_with_associations
|
109
|
-
return super { |r| yield r } if block_given?
|
110
|
-
|
111
|
-
records = super
|
112
|
-
if Bullet.start?
|
113
|
-
associations = (eager_load_values + includes_values).uniq
|
114
|
-
records.each { |record| Bullet::Detector::Association.add_object_associations(record, associations) }
|
115
|
-
Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, associations)
|
116
|
-
end
|
117
|
-
records
|
118
|
-
end
|
119
|
-
end
|
120
|
-
)
|
121
|
-
|
122
105
|
::ActiveRecord::Associations::JoinDependency.prepend(
|
123
106
|
Module.new do
|
124
107
|
def instantiate(result_set, strict_loading_value, &block)
|
@@ -176,6 +159,17 @@ module Bullet
|
|
176
159
|
end
|
177
160
|
)
|
178
161
|
|
162
|
+
::ActiveRecord::Associations::Association.prepend(
|
163
|
+
Module.new do
|
164
|
+
def inversed_from(record)
|
165
|
+
if Bullet.start?
|
166
|
+
Bullet::Detector::NPlusOneQuery.add_inversed_object(owner, reflection.name)
|
167
|
+
end
|
168
|
+
super
|
169
|
+
end
|
170
|
+
end
|
171
|
+
)
|
172
|
+
|
179
173
|
::ActiveRecord::Associations::CollectionAssociation.prepend(
|
180
174
|
Module.new do
|
181
175
|
def load_target
|
@@ -183,10 +177,12 @@ module Bullet
|
|
183
177
|
|
184
178
|
if Bullet.start?
|
185
179
|
if is_a? ::ActiveRecord::Associations::ThroughAssociation
|
186
|
-
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
|
187
180
|
association = owner.association(reflection.through_reflection.name)
|
188
|
-
|
189
|
-
Bullet::Detector::NPlusOneQuery.call_association(
|
181
|
+
if association.loaded?
|
182
|
+
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
|
183
|
+
Array.wrap(association.target).each do |through_record|
|
184
|
+
Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
|
185
|
+
end
|
190
186
|
end
|
191
187
|
|
192
188
|
if reflection.through_reflection != through_reflection
|
@@ -232,7 +228,7 @@ module Bullet
|
|
232
228
|
if is_a? ::ActiveRecord::Associations::ThroughAssociation
|
233
229
|
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
|
234
230
|
association = owner.association(reflection.through_reflection.name)
|
235
|
-
Array(association.target).each do |through_record|
|
231
|
+
Array.wrap(association.target).each do |through_record|
|
236
232
|
Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
|
237
233
|
end
|
238
234
|
|