bullet 7.0.6 → 7.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -1
- data/README.md +3 -0
- data/lib/bullet/active_record4.rb +9 -0
- data/lib/bullet/active_record41.rb +9 -0
- data/lib/bullet/active_record42.rb +9 -0
- data/lib/bullet/active_record5.rb +11 -0
- data/lib/bullet/active_record52.rb +11 -0
- data/lib/bullet/active_record60.rb +11 -0
- data/lib/bullet/active_record61.rb +11 -0
- data/lib/bullet/active_record70.rb +19 -6
- data/lib/bullet/active_record71.rb +297 -0
- data/lib/bullet/dependency.rb +12 -0
- data/lib/bullet/detector/unused_eager_loading.rb +1 -1
- data/lib/bullet/mongoid8x.rb +59 -0
- data/lib/bullet/notification/counter_cache.rb +1 -1
- data/lib/bullet/rack.rb +1 -1
- data/lib/bullet/version.rb +1 -1
- data/lib/bullet.rb +6 -2
- metadata +7 -155
- data/.github/workflows/main.yml +0 -82
- data/.gitignore +0 -15
- data/.rspec +0 -2
- data/Gemfile +0 -24
- data/Gemfile.mongoid +0 -12
- data/Gemfile.mongoid-4.0 +0 -15
- data/Gemfile.mongoid-5.0 +0 -15
- data/Gemfile.mongoid-6.0 +0 -15
- data/Gemfile.mongoid-7.0 +0 -15
- data/Gemfile.rails-4.0 +0 -16
- data/Gemfile.rails-4.1 +0 -16
- data/Gemfile.rails-4.2 +0 -16
- data/Gemfile.rails-5.0 +0 -15
- data/Gemfile.rails-5.1 +0 -15
- data/Gemfile.rails-5.2 +0 -15
- data/Gemfile.rails-6.0 +0 -15
- data/Gemfile.rails-6.1 +0 -15
- data/Gemfile.rails-7.0 +0 -10
- data/Guardfile +0 -8
- data/Hacking.md +0 -75
- data/Rakefile +0 -51
- data/bullet.gemspec +0 -33
- data/perf/benchmark.rb +0 -118
- data/rails/init.rb +0 -3
- data/spec/bullet/detector/association_spec.rb +0 -28
- data/spec/bullet/detector/base_spec.rb +0 -10
- data/spec/bullet/detector/counter_cache_spec.rb +0 -58
- data/spec/bullet/detector/n_plus_one_query_spec.rb +0 -150
- data/spec/bullet/detector/unused_eager_loading_spec.rb +0 -126
- data/spec/bullet/ext/object_spec.rb +0 -44
- data/spec/bullet/ext/string_spec.rb +0 -15
- data/spec/bullet/notification/base_spec.rb +0 -94
- data/spec/bullet/notification/counter_cache_spec.rb +0 -14
- data/spec/bullet/notification/n_plus_one_query_spec.rb +0 -29
- data/spec/bullet/notification/unused_eager_loading_spec.rb +0 -18
- data/spec/bullet/notification_collector_spec.rb +0 -34
- data/spec/bullet/rack_spec.rb +0 -296
- data/spec/bullet/registry/association_spec.rb +0 -28
- data/spec/bullet/registry/base_spec.rb +0 -46
- data/spec/bullet/registry/object_spec.rb +0 -26
- data/spec/bullet/stack_trace_filter_spec.rb +0 -26
- data/spec/bullet_spec.rb +0 -136
- data/spec/integration/active_record/association_spec.rb +0 -822
- data/spec/integration/counter_cache_spec.rb +0 -68
- data/spec/integration/mongoid/association_spec.rb +0 -246
- data/spec/models/address.rb +0 -5
- data/spec/models/attachment.rb +0 -5
- data/spec/models/author.rb +0 -5
- data/spec/models/base_user.rb +0 -7
- data/spec/models/category.rb +0 -12
- data/spec/models/city.rb +0 -5
- data/spec/models/client.rb +0 -8
- data/spec/models/comment.rb +0 -8
- data/spec/models/company.rb +0 -5
- data/spec/models/country.rb +0 -5
- data/spec/models/deal.rb +0 -5
- data/spec/models/document.rb +0 -7
- data/spec/models/entry.rb +0 -5
- data/spec/models/firm.rb +0 -7
- data/spec/models/folder.rb +0 -4
- data/spec/models/group.rb +0 -4
- data/spec/models/mongoid/address.rb +0 -9
- data/spec/models/mongoid/category.rb +0 -10
- data/spec/models/mongoid/comment.rb +0 -9
- data/spec/models/mongoid/company.rb +0 -9
- data/spec/models/mongoid/entry.rb +0 -9
- data/spec/models/mongoid/post.rb +0 -14
- data/spec/models/mongoid/user.rb +0 -7
- data/spec/models/newspaper.rb +0 -5
- data/spec/models/page.rb +0 -4
- data/spec/models/person.rb +0 -5
- data/spec/models/pet.rb +0 -5
- data/spec/models/post.rb +0 -34
- data/spec/models/relationship.rb +0 -6
- data/spec/models/reply.rb +0 -5
- data/spec/models/role.rb +0 -7
- data/spec/models/student.rb +0 -5
- data/spec/models/submission.rb +0 -7
- data/spec/models/teacher.rb +0 -5
- data/spec/models/user.rb +0 -8
- data/spec/models/writer.rb +0 -4
- data/spec/spec_helper.rb +0 -97
- data/spec/support/bullet_ext.rb +0 -56
- data/spec/support/mongo_seed.rb +0 -59
- data/spec/support/rack_double.rb +0 -49
- data/spec/support/sqlite_seed.rb +0 -284
- data/test.sh +0 -15
- data/update.sh +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3556ad95bac8e87086710acf1c5b7ea5aa8252ee83ab3b20dfb4ec9e06a06474
|
4
|
+
data.tar.gz: 5d3695f3e2ab1ff51232e56d056aaf994630d465f5902106ceef125a7c6426d9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 150e4ba5ae1900d1e50b87cfed8f325ff2615bbe613e908bc5e253d7072a0018869a6a67ca311a3f22cd190cadc87882e99700e0f9ae1e54277b64ddd0d2fe45
|
7
|
+
data.tar.gz: cf3c2bf147e67915dd46670a8cf2b77b90c236fddca56fe1663ff62d8bf10a1a10506ee54773a28b7759d892ed6ed7fcdd7e0952d6b67ec8074b5a66abce0a8f
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
## Next Release
|
2
2
|
|
3
|
+
## 7.1.0 (10/06/2023)
|
4
|
+
|
5
|
+
* Support rails 7.1
|
6
|
+
* Alias `Bullet.enable?` to `enabled?`, and `Bullet.enable=` to `enabled=`
|
7
|
+
* Added `always_append_html_body` option, so the html snippet is always included even if there are no notifications
|
8
|
+
* Added detection of n+1 count queries from `count` method
|
9
|
+
* Changed the counter cache notification title to recommend using `size`
|
10
|
+
|
11
|
+
## 7.0.7 (03/01/2023)
|
12
|
+
|
13
|
+
* Check `Rails.application.config.content_security_policy` before insert `Bullet::Rack`
|
14
|
+
|
3
15
|
## 7.0.6 (03/01/2023)
|
4
16
|
|
5
17
|
* Better way to check if `ActionDispatch::ContentSecurityPolicy::Middleware` exists
|
@@ -93,7 +105,7 @@
|
|
93
105
|
|
94
106
|
* Fix through reflection for rails 5.x
|
95
107
|
* Fix false positive in after_save/after_create callbacks
|
96
|
-
* Don't
|
108
|
+
* Don't trigger a preload error on "manual" preloads
|
97
109
|
* Avoid Bullet from making extra queries in mongoid6
|
98
110
|
* Support option for #first and #last on mongoid6.x
|
99
111
|
* Fix duplicate logs in mongoid 4.x and 5.x version
|
data/README.md
CHANGED
@@ -101,6 +101,7 @@ The code above will enable all of the Bullet notification systems:
|
|
101
101
|
item is a line number, a Range of line numbers, or a (bare) method name, to exclude only particular lines in a file.
|
102
102
|
* `Bullet.slack`: add notifications to slack
|
103
103
|
* `Bullet.raise`: raise errors, useful for making your specs fail unless they have optimized queries
|
104
|
+
* `Bullet.always_append_html_body`: always append the html body even if no notifications are present. Note: `console` or `add_footer` must also be true. Useful for Single Page Applications where the initial page load might not have any notifications present.
|
104
105
|
|
105
106
|
|
106
107
|
Bullet also allows you to disable any of its detectors.
|
@@ -119,6 +120,8 @@ Bullet.unused_eager_loading_enable = false
|
|
119
120
|
Bullet.counter_cache_enable = false
|
120
121
|
```
|
121
122
|
|
123
|
+
Note: When calling `Bullet.enable`, all other detectors are reset to their defaults (`true`) and need reconfiguring.
|
124
|
+
|
122
125
|
## Safe list
|
123
126
|
|
124
127
|
Sometimes Bullet may notify you of query problems you don't care to fix, or
|
@@ -176,6 +176,15 @@ module Bullet
|
|
176
176
|
result
|
177
177
|
end
|
178
178
|
end
|
179
|
+
|
180
|
+
::ActiveRecord::Associations::CollectionProxy.class_eval do
|
181
|
+
def count
|
182
|
+
if Bullet.start?
|
183
|
+
Bullet::Detector::CounterCache.add_counter_cache(proxy_association.owner, proxy_association.reflection.name)
|
184
|
+
end
|
185
|
+
super
|
186
|
+
end
|
187
|
+
end
|
179
188
|
end
|
180
189
|
end
|
181
190
|
end
|
@@ -168,6 +168,15 @@ module Bullet
|
|
168
168
|
origin_count_records
|
169
169
|
end
|
170
170
|
end
|
171
|
+
|
172
|
+
::ActiveRecord::Associations::CollectionProxy.class_eval do
|
173
|
+
def count
|
174
|
+
if Bullet.start?
|
175
|
+
Bullet::Detector::CounterCache.add_counter_cache(proxy_association.owner, proxy_association.reflection.name)
|
176
|
+
end
|
177
|
+
super
|
178
|
+
end
|
179
|
+
end
|
171
180
|
end
|
172
181
|
end
|
173
182
|
end
|
@@ -233,6 +233,15 @@ module Bullet
|
|
233
233
|
origin_count_records
|
234
234
|
end
|
235
235
|
end
|
236
|
+
|
237
|
+
::ActiveRecord::Associations::CollectionProxy.class_eval do
|
238
|
+
def count
|
239
|
+
if Bullet.start?
|
240
|
+
Bullet::Detector::CounterCache.add_counter_cache(proxy_association.owner, proxy_association.reflection.name)
|
241
|
+
end
|
242
|
+
super
|
243
|
+
end
|
244
|
+
end
|
236
245
|
end
|
237
246
|
end
|
238
247
|
end
|
@@ -260,6 +260,17 @@ module Bullet
|
|
260
260
|
end
|
261
261
|
end
|
262
262
|
)
|
263
|
+
|
264
|
+
::ActiveRecord::Associations::CollectionProxy.prepend(
|
265
|
+
Module.new do
|
266
|
+
def count
|
267
|
+
if Bullet.start? && !proxy_association.is_a?(::ActiveRecord::Associations::ThroughAssociation)
|
268
|
+
Bullet::Detector::CounterCache.add_counter_cache(proxy_association.owner, proxy_association.reflection.name)
|
269
|
+
end
|
270
|
+
super
|
271
|
+
end
|
272
|
+
end
|
273
|
+
)
|
263
274
|
end
|
264
275
|
end
|
265
276
|
end
|
@@ -242,6 +242,17 @@ module Bullet
|
|
242
242
|
end
|
243
243
|
end
|
244
244
|
)
|
245
|
+
|
246
|
+
::ActiveRecord::Associations::CollectionProxy.prepend(
|
247
|
+
Module.new do
|
248
|
+
def count
|
249
|
+
if Bullet.start? && !proxy_association.is_a?(::ActiveRecord::Associations::ThroughAssociation)
|
250
|
+
Bullet::Detector::CounterCache.add_counter_cache(proxy_association.owner, proxy_association.reflection.name)
|
251
|
+
end
|
252
|
+
super
|
253
|
+
end
|
254
|
+
end
|
255
|
+
)
|
245
256
|
end
|
246
257
|
end
|
247
258
|
end
|
@@ -269,6 +269,17 @@ module Bullet
|
|
269
269
|
end
|
270
270
|
end
|
271
271
|
)
|
272
|
+
|
273
|
+
::ActiveRecord::Associations::CollectionProxy.prepend(
|
274
|
+
Module.new do
|
275
|
+
def count
|
276
|
+
if Bullet.start? && !proxy_association.is_a?(::ActiveRecord::Associations::ThroughAssociation)
|
277
|
+
Bullet::Detector::CounterCache.add_counter_cache(proxy_association.owner, proxy_association.reflection.name)
|
278
|
+
end
|
279
|
+
super
|
280
|
+
end
|
281
|
+
end
|
282
|
+
)
|
272
283
|
end
|
273
284
|
end
|
274
285
|
end
|
@@ -269,6 +269,17 @@ module Bullet
|
|
269
269
|
end
|
270
270
|
end
|
271
271
|
)
|
272
|
+
|
273
|
+
::ActiveRecord::Associations::CollectionProxy.prepend(
|
274
|
+
Module.new do
|
275
|
+
def count
|
276
|
+
if Bullet.start? && !proxy_association.is_a?(::ActiveRecord::Associations::ThroughAssociation)
|
277
|
+
Bullet::Detector::CounterCache.add_counter_cache(proxy_association.owner, proxy_association.reflection.name)
|
278
|
+
end
|
279
|
+
super
|
280
|
+
end
|
281
|
+
end
|
282
|
+
)
|
272
283
|
end
|
273
284
|
end
|
274
285
|
end
|
@@ -91,16 +91,18 @@ module Bullet
|
|
91
91
|
|
92
92
|
::ActiveRecord::Associations::Preloader::ThroughAssociation.prepend(
|
93
93
|
Module.new do
|
94
|
-
def
|
95
|
-
if Bullet.start? && !defined?(@
|
96
|
-
|
97
|
-
|
98
|
-
|
94
|
+
def source_preloaders
|
95
|
+
if Bullet.start? && !defined?(@source_preloaders)
|
96
|
+
preloaders = super
|
97
|
+
preloaders.each do |preloader|
|
98
|
+
reflection_name = preloader.send(:reflection).name
|
99
|
+
preloader.send(:owners).each do |owner|
|
99
100
|
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection_name)
|
100
101
|
end
|
101
102
|
end
|
103
|
+
else
|
104
|
+
super
|
102
105
|
end
|
103
|
-
super
|
104
106
|
end
|
105
107
|
end
|
106
108
|
)
|
@@ -279,6 +281,17 @@ module Bullet
|
|
279
281
|
end
|
280
282
|
end
|
281
283
|
)
|
284
|
+
|
285
|
+
::ActiveRecord::Associations::CollectionProxy.prepend(
|
286
|
+
Module.new do
|
287
|
+
def count
|
288
|
+
if Bullet.start? && !proxy_association.is_a?(::ActiveRecord::Associations::ThroughAssociation)
|
289
|
+
Bullet::Detector::CounterCache.add_counter_cache(proxy_association.owner, proxy_association.reflection.name)
|
290
|
+
end
|
291
|
+
super
|
292
|
+
end
|
293
|
+
end
|
294
|
+
)
|
282
295
|
end
|
283
296
|
end
|
284
297
|
end
|
@@ -0,0 +1,297 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bullet
|
4
|
+
module SaveWithBulletSupport
|
5
|
+
def _create_record(*)
|
6
|
+
super do
|
7
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(self)
|
8
|
+
yield(self) if block_given?
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module ActiveRecord
|
14
|
+
def self.enable
|
15
|
+
require 'active_record'
|
16
|
+
::ActiveRecord::Base.extend(
|
17
|
+
Module.new do
|
18
|
+
def find_by_sql(sql, binds = [], preparable: nil, &block)
|
19
|
+
result = super
|
20
|
+
if Bullet.start?
|
21
|
+
if result.is_a? Array
|
22
|
+
if result.size > 1
|
23
|
+
Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
|
24
|
+
Bullet::Detector::CounterCache.add_possible_objects(result)
|
25
|
+
elsif result.size == 1
|
26
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(result.first)
|
27
|
+
Bullet::Detector::CounterCache.add_impossible_object(result.first)
|
28
|
+
end
|
29
|
+
elsif result.is_a? ::ActiveRecord::Base
|
30
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(result)
|
31
|
+
Bullet::Detector::CounterCache.add_impossible_object(result)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
result
|
35
|
+
end
|
36
|
+
end
|
37
|
+
)
|
38
|
+
|
39
|
+
::ActiveRecord::Base.prepend(SaveWithBulletSupport)
|
40
|
+
|
41
|
+
::ActiveRecord::Relation.prepend(
|
42
|
+
Module.new do
|
43
|
+
# if select a collection of objects, then these objects have possible to cause N+1 query.
|
44
|
+
# if select only one object, then the only one object has impossible to cause N+1 query.
|
45
|
+
def records
|
46
|
+
result = super
|
47
|
+
if Bullet.start?
|
48
|
+
if result.first.class.name !~ /^HABTM_/
|
49
|
+
if result.size > 1
|
50
|
+
Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
|
51
|
+
Bullet::Detector::CounterCache.add_possible_objects(result)
|
52
|
+
elsif result.size == 1
|
53
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(result.first)
|
54
|
+
Bullet::Detector::CounterCache.add_impossible_object(result.first)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
result
|
59
|
+
end
|
60
|
+
end
|
61
|
+
)
|
62
|
+
|
63
|
+
::ActiveRecord::Associations::Preloader::Batch.prepend(
|
64
|
+
Module.new do
|
65
|
+
def call
|
66
|
+
if Bullet.start?
|
67
|
+
@preloaders.each do |preloader|
|
68
|
+
preloader.records.each { |record| Bullet::Detector::Association.add_object_associations(record, preloader.associations) }
|
69
|
+
Bullet::Detector::UnusedEagerLoading.add_eager_loadings(preloader.records, preloader.associations)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
super
|
73
|
+
end
|
74
|
+
end
|
75
|
+
)
|
76
|
+
|
77
|
+
::ActiveRecord::Associations::Preloader::Branch.prepend(
|
78
|
+
Module.new do
|
79
|
+
def preloaders_for_reflection(reflection, reflection_records)
|
80
|
+
if Bullet.start?
|
81
|
+
reflection_records.compact!
|
82
|
+
if reflection_records.first.class.name !~ /^HABTM_/
|
83
|
+
reflection_records.each { |record| Bullet::Detector::Association.add_object_associations(record, reflection.name) }
|
84
|
+
Bullet::Detector::UnusedEagerLoading.add_eager_loadings(reflection_records, reflection.name)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
super
|
88
|
+
end
|
89
|
+
end
|
90
|
+
)
|
91
|
+
|
92
|
+
::ActiveRecord::Associations::Preloader::ThroughAssociation.prepend(
|
93
|
+
Module.new do
|
94
|
+
def source_preloaders
|
95
|
+
if Bullet.start? && !defined?(@source_preloaders)
|
96
|
+
preloaders = super
|
97
|
+
preloaders.each do |preloader|
|
98
|
+
reflection_name = preloader.send(:reflection).name
|
99
|
+
preloader.send(:owners).each do |owner|
|
100
|
+
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection_name)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
else
|
104
|
+
super
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
)
|
109
|
+
|
110
|
+
::ActiveRecord::Associations::JoinDependency.prepend(
|
111
|
+
Module.new do
|
112
|
+
def instantiate(result_set, strict_loading_value, &block)
|
113
|
+
@bullet_eager_loadings = {}
|
114
|
+
records = super
|
115
|
+
|
116
|
+
if Bullet.start?
|
117
|
+
@bullet_eager_loadings.each do |_klazz, eager_loadings_hash|
|
118
|
+
objects = eager_loadings_hash.keys
|
119
|
+
Bullet::Detector::UnusedEagerLoading.add_eager_loadings(
|
120
|
+
objects,
|
121
|
+
eager_loadings_hash[objects.first].to_a
|
122
|
+
)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
records
|
126
|
+
end
|
127
|
+
|
128
|
+
def construct(ar_parent, parent, row, seen, model_cache, strict_loading_value)
|
129
|
+
if Bullet.start?
|
130
|
+
unless ar_parent.nil?
|
131
|
+
parent.children.each do |node|
|
132
|
+
key = aliases.column_alias(node, node.primary_key)
|
133
|
+
id = row[key]
|
134
|
+
next unless id.nil?
|
135
|
+
|
136
|
+
associations = node.reflection.name
|
137
|
+
Bullet::Detector::Association.add_object_associations(ar_parent, associations)
|
138
|
+
Bullet::Detector::NPlusOneQuery.call_association(ar_parent, associations)
|
139
|
+
@bullet_eager_loadings[ar_parent.class] ||= {}
|
140
|
+
@bullet_eager_loadings[ar_parent.class][ar_parent] ||= Set.new
|
141
|
+
@bullet_eager_loadings[ar_parent.class][ar_parent] << associations
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
super
|
147
|
+
end
|
148
|
+
|
149
|
+
# call join associations
|
150
|
+
def construct_model(record, node, row, model_cache, id, strict_loading_value)
|
151
|
+
result = super
|
152
|
+
|
153
|
+
if Bullet.start?
|
154
|
+
associations = node.reflection.name
|
155
|
+
Bullet::Detector::Association.add_object_associations(record, associations)
|
156
|
+
Bullet::Detector::NPlusOneQuery.call_association(record, associations)
|
157
|
+
@bullet_eager_loadings[record.class] ||= {}
|
158
|
+
@bullet_eager_loadings[record.class][record] ||= Set.new
|
159
|
+
@bullet_eager_loadings[record.class][record] << associations
|
160
|
+
end
|
161
|
+
|
162
|
+
result
|
163
|
+
end
|
164
|
+
end
|
165
|
+
)
|
166
|
+
|
167
|
+
::ActiveRecord::Associations::Association.prepend(
|
168
|
+
Module.new do
|
169
|
+
def inversed_from(record)
|
170
|
+
if Bullet.start?
|
171
|
+
Bullet::Detector::NPlusOneQuery.add_inversed_object(owner, reflection.name)
|
172
|
+
end
|
173
|
+
super
|
174
|
+
end
|
175
|
+
|
176
|
+
def inversed_from_queries(record)
|
177
|
+
if Bullet.start? && inversable?(record)
|
178
|
+
Bullet::Detector::NPlusOneQuery.add_inversed_object(owner, reflection.name)
|
179
|
+
end
|
180
|
+
super
|
181
|
+
end
|
182
|
+
end
|
183
|
+
)
|
184
|
+
|
185
|
+
::ActiveRecord::Associations::CollectionAssociation.prepend(
|
186
|
+
Module.new do
|
187
|
+
def load_target
|
188
|
+
records = super
|
189
|
+
|
190
|
+
if Bullet.start?
|
191
|
+
if is_a? ::ActiveRecord::Associations::ThroughAssociation
|
192
|
+
association = owner.association(reflection.through_reflection.name)
|
193
|
+
if association.loaded?
|
194
|
+
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
|
195
|
+
Array.wrap(association.target).each do |through_record|
|
196
|
+
Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
|
197
|
+
end
|
198
|
+
|
199
|
+
if reflection.through_reflection != through_reflection
|
200
|
+
Bullet::Detector::NPlusOneQuery.call_association(owner, through_reflection.name)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
|
205
|
+
if records.first.class.name !~ /^HABTM_/
|
206
|
+
if records.size > 1
|
207
|
+
Bullet::Detector::NPlusOneQuery.add_possible_objects(records)
|
208
|
+
Bullet::Detector::CounterCache.add_possible_objects(records)
|
209
|
+
elsif records.size == 1
|
210
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(records.first)
|
211
|
+
Bullet::Detector::CounterCache.add_impossible_object(records.first)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
records
|
216
|
+
end
|
217
|
+
|
218
|
+
def empty?
|
219
|
+
if Bullet.start? && !reflection.has_cached_counter?
|
220
|
+
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
|
221
|
+
end
|
222
|
+
super
|
223
|
+
end
|
224
|
+
|
225
|
+
def include?(object)
|
226
|
+
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name) if Bullet.start?
|
227
|
+
super
|
228
|
+
end
|
229
|
+
end
|
230
|
+
)
|
231
|
+
|
232
|
+
::ActiveRecord::Associations::SingularAssociation.prepend(
|
233
|
+
Module.new do
|
234
|
+
# call has_one and belongs_to associations
|
235
|
+
def reader
|
236
|
+
result = super
|
237
|
+
|
238
|
+
if Bullet.start?
|
239
|
+
if owner.class.name !~ /^HABTM_/
|
240
|
+
if is_a? ::ActiveRecord::Associations::ThroughAssociation
|
241
|
+
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
|
242
|
+
association = owner.association(reflection.through_reflection.name)
|
243
|
+
Array.wrap(association.target).each do |through_record|
|
244
|
+
Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
|
245
|
+
end
|
246
|
+
|
247
|
+
if reflection.through_reflection != through_reflection
|
248
|
+
Bullet::Detector::NPlusOneQuery.call_association(owner, through_reflection.name)
|
249
|
+
end
|
250
|
+
end
|
251
|
+
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
|
252
|
+
|
253
|
+
if Bullet::Detector::NPlusOneQuery.impossible?(owner)
|
254
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(result) if result
|
255
|
+
else
|
256
|
+
Bullet::Detector::NPlusOneQuery.add_possible_objects(result) if result
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
result
|
261
|
+
end
|
262
|
+
end
|
263
|
+
)
|
264
|
+
|
265
|
+
::ActiveRecord::Associations::HasManyAssociation.prepend(
|
266
|
+
Module.new do
|
267
|
+
def empty?
|
268
|
+
result = super
|
269
|
+
if Bullet.start? && !reflection.has_cached_counter?
|
270
|
+
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
|
271
|
+
end
|
272
|
+
result
|
273
|
+
end
|
274
|
+
|
275
|
+
def count_records
|
276
|
+
result = reflection.has_cached_counter?
|
277
|
+
if Bullet.start? && !result && !is_a?(::ActiveRecord::Associations::ThroughAssociation)
|
278
|
+
Bullet::Detector::CounterCache.add_counter_cache(owner, reflection.name)
|
279
|
+
end
|
280
|
+
super
|
281
|
+
end
|
282
|
+
end
|
283
|
+
)
|
284
|
+
|
285
|
+
::ActiveRecord::Associations::CollectionProxy.prepend(
|
286
|
+
Module.new do
|
287
|
+
def count
|
288
|
+
if Bullet.start? && !proxy_association.is_a?(::ActiveRecord::Associations::ThroughAssociation)
|
289
|
+
Bullet::Detector::CounterCache.add_counter_cache(proxy_association.owner, proxy_association.reflection.name)
|
290
|
+
end
|
291
|
+
super
|
292
|
+
end
|
293
|
+
end
|
294
|
+
)
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
data/lib/bullet/dependency.rb
CHANGED
@@ -31,6 +31,8 @@ module Bullet
|
|
31
31
|
'active_record61'
|
32
32
|
elsif active_record70?
|
33
33
|
'active_record70'
|
34
|
+
elsif active_record71?
|
35
|
+
'active_record71'
|
34
36
|
else
|
35
37
|
raise "Bullet does not support active_record #{::ActiveRecord::VERSION::STRING} yet"
|
36
38
|
end
|
@@ -48,6 +50,8 @@ module Bullet
|
|
48
50
|
'mongoid6x'
|
49
51
|
elsif mongoid7x?
|
50
52
|
'mongoid7x'
|
53
|
+
elsif mongoid8x?
|
54
|
+
'mongoid8x'
|
51
55
|
else
|
52
56
|
raise "Bullet does not support mongoid #{::Mongoid::VERSION} yet"
|
53
57
|
end
|
@@ -106,6 +110,10 @@ module Bullet
|
|
106
110
|
active_record7? && ::ActiveRecord::VERSION::MINOR == 0
|
107
111
|
end
|
108
112
|
|
113
|
+
def active_record71?
|
114
|
+
active_record7? && ::ActiveRecord::VERSION::MINOR == 1
|
115
|
+
end
|
116
|
+
|
109
117
|
def mongoid4x?
|
110
118
|
mongoid? && ::Mongoid::VERSION =~ /\A4/
|
111
119
|
end
|
@@ -121,5 +129,9 @@ module Bullet
|
|
121
129
|
def mongoid7x?
|
122
130
|
mongoid? && ::Mongoid::VERSION =~ /\A7/
|
123
131
|
end
|
132
|
+
|
133
|
+
def mongoid8x?
|
134
|
+
mongoid? && ::Mongoid::VERSION =~ /\A8/
|
135
|
+
end
|
124
136
|
end
|
125
137
|
end
|
@@ -10,7 +10,7 @@ module Bullet
|
|
10
10
|
# check if there are unused preload associations.
|
11
11
|
# get related_objects from eager_loadings associated with object and associations
|
12
12
|
# get call_object_association from associations of call_object_associations whose object is in related_objects
|
13
|
-
# if association not in call_object_association, then the object => association - call_object_association is
|
13
|
+
# if association not in call_object_association, then the object => association - call_object_association is unused preload associations
|
14
14
|
def check_unused_preload_associations
|
15
15
|
return unless Bullet.start?
|
16
16
|
return unless Bullet.unused_eager_loading_enable?
|
@@ -0,0 +1,59 @@
|
|
1
|
+
|
2
|
+
module Bullet
|
3
|
+
module Mongoid
|
4
|
+
def self.enable
|
5
|
+
require 'mongoid'
|
6
|
+
::Mongoid::Contextual::Mongo.class_eval do
|
7
|
+
alias_method :origin_first, :first
|
8
|
+
alias_method :origin_last, :last
|
9
|
+
alias_method :origin_each, :each
|
10
|
+
alias_method :origin_eager_load, :eager_load
|
11
|
+
|
12
|
+
def first(opts = {})
|
13
|
+
result = origin_first(opts)
|
14
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(result) if result
|
15
|
+
result
|
16
|
+
end
|
17
|
+
|
18
|
+
def last(opts = {})
|
19
|
+
result = origin_last(opts)
|
20
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(result) if result
|
21
|
+
result
|
22
|
+
end
|
23
|
+
|
24
|
+
def each(&block)
|
25
|
+
return to_enum unless block_given?
|
26
|
+
records = []
|
27
|
+
origin_each { |record| records << record }
|
28
|
+
if records.length > 1
|
29
|
+
Bullet::Detector::NPlusOneQuery.add_possible_objects(records)
|
30
|
+
elsif records.size == 1
|
31
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(records.first)
|
32
|
+
end
|
33
|
+
records.each(&block)
|
34
|
+
end
|
35
|
+
|
36
|
+
def eager_load(docs)
|
37
|
+
associations = criteria.inclusions.map(&:name)
|
38
|
+
docs.each do |doc|
|
39
|
+
Bullet::Detector::NPlusOneQuery.add_object_associations(doc, associations)
|
40
|
+
end
|
41
|
+
Bullet::Detector::UnusedEagerLoading.add_eager_loadings(docs, associations)
|
42
|
+
origin_eager_load(docs)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
::Mongoid::Association::Accessors.class_eval do
|
47
|
+
alias_method :origin_get_relation, :get_relation
|
48
|
+
|
49
|
+
def get_relation(name, association, object, reload = false)
|
50
|
+
result = origin_get_relation(name, association, object, reload)
|
51
|
+
unless association.embedded?
|
52
|
+
Bullet::Detector::NPlusOneQuery.call_association(self, name)
|
53
|
+
end
|
54
|
+
result
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/bullet/rack.rb
CHANGED
@@ -18,7 +18,7 @@ module Bullet
|
|
18
18
|
|
19
19
|
response_body = nil
|
20
20
|
|
21
|
-
if Bullet.notification?
|
21
|
+
if Bullet.notification? || Bullet.always_append_html_body
|
22
22
|
if Bullet.inject_into_page? && !file?(headers) && !sse?(headers) && !empty?(response) && status == 200
|
23
23
|
if html_request?(headers, response)
|
24
24
|
response_body = response_body(response)
|
data/lib/bullet/version.rb
CHANGED