bullet 7.1.6 → 7.2.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 +5 -0
- data/lib/bullet/active_record5.rb +2 -2
- data/lib/bullet/active_record60.rb +2 -2
- data/lib/bullet/active_record72.rb +318 -0
- data/lib/bullet/dependency.rb +6 -0
- data/lib/bullet/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a0528fba283865b1a94ba6a82d3f5941c63a62e7b34a08332d6208dfde7f28ba
|
4
|
+
data.tar.gz: 21ad1b7a9c1ab8473ddfff4fcd260346b5088a2f8cf615fbe74abfbe2e70c307
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8f6a75db29ab14c89ebd57664f7d96ee5f006fbc816dcbc442678ded0171712aadd360dbb204a567519cab8a49879c067b83a090ea3a8999d212b6801d60fa92
|
7
|
+
data.tar.gz: 4b51f257fb70205d068e7f233b0e5e30967da936e19481bd9d956b0303f85b67b95792a00a92f272e04333d3861dd69d6ac916c156d06b5db9f5136e0b543dd9
|
data/CHANGELOG.md
CHANGED
@@ -273,7 +273,7 @@ module Bullet
|
|
273
273
|
|
274
274
|
::ActiveRecord::Associations::CollectionProxy.prepend(
|
275
275
|
Module.new do
|
276
|
-
def count
|
276
|
+
def count(column_name = nil)
|
277
277
|
if Bullet.start? && !proxy_association.is_a?(::ActiveRecord::Associations::ThroughAssociation)
|
278
278
|
Bullet::Detector::CounterCache.add_counter_cache(
|
279
279
|
proxy_association.owner,
|
@@ -284,7 +284,7 @@ module Bullet
|
|
284
284
|
proxy_association.reflection.name
|
285
285
|
)
|
286
286
|
end
|
287
|
-
super
|
287
|
+
super(column_name)
|
288
288
|
end
|
289
289
|
end
|
290
290
|
)
|
@@ -282,7 +282,7 @@ module Bullet
|
|
282
282
|
|
283
283
|
::ActiveRecord::Associations::CollectionProxy.prepend(
|
284
284
|
Module.new do
|
285
|
-
def count
|
285
|
+
def count(column_name = nil)
|
286
286
|
if Bullet.start? && !proxy_association.is_a?(::ActiveRecord::Associations::ThroughAssociation)
|
287
287
|
Bullet::Detector::CounterCache.add_counter_cache(
|
288
288
|
proxy_association.owner,
|
@@ -293,7 +293,7 @@ module Bullet
|
|
293
293
|
proxy_association.reflection.name
|
294
294
|
)
|
295
295
|
end
|
296
|
-
super
|
296
|
+
super(column_name)
|
297
297
|
end
|
298
298
|
end
|
299
299
|
)
|
@@ -0,0 +1,318 @@
|
|
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, allow_retry: false, &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|
|
69
|
+
Bullet::Detector::Association.add_object_associations(record, preloader.associations)
|
70
|
+
}
|
71
|
+
Bullet::Detector::UnusedEagerLoading.add_eager_loadings(preloader.records, preloader.associations)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
super
|
75
|
+
end
|
76
|
+
end
|
77
|
+
)
|
78
|
+
|
79
|
+
::ActiveRecord::Associations::Preloader::Branch.prepend(
|
80
|
+
Module.new do
|
81
|
+
def preloaders_for_reflection(reflection, reflection_records)
|
82
|
+
if Bullet.start?
|
83
|
+
reflection_records.compact!
|
84
|
+
if reflection_records.first.class.name !~ /^HABTM_/
|
85
|
+
reflection_records.each { |record|
|
86
|
+
Bullet::Detector::Association.add_object_associations(record, reflection.name)
|
87
|
+
}
|
88
|
+
Bullet::Detector::UnusedEagerLoading.add_eager_loadings(reflection_records, reflection.name)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
super
|
92
|
+
end
|
93
|
+
end
|
94
|
+
)
|
95
|
+
|
96
|
+
::ActiveRecord::Associations::Preloader::ThroughAssociation.prepend(
|
97
|
+
Module.new do
|
98
|
+
def source_preloaders
|
99
|
+
if Bullet.start? && !defined?(@source_preloaders)
|
100
|
+
preloaders = super
|
101
|
+
preloaders.each do |preloader|
|
102
|
+
reflection_name = preloader.send(:reflection).name
|
103
|
+
preloader.send(:owners).each do |owner|
|
104
|
+
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection_name)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
else
|
108
|
+
super
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
)
|
113
|
+
|
114
|
+
::ActiveRecord::Associations::JoinDependency.prepend(
|
115
|
+
Module.new do
|
116
|
+
def instantiate(result_set, strict_loading_value, &block)
|
117
|
+
@bullet_eager_loadings = {}
|
118
|
+
records = super
|
119
|
+
|
120
|
+
if Bullet.start?
|
121
|
+
@bullet_eager_loadings.each do |_klazz, eager_loadings_hash|
|
122
|
+
objects = eager_loadings_hash.keys
|
123
|
+
Bullet::Detector::UnusedEagerLoading.add_eager_loadings(
|
124
|
+
objects,
|
125
|
+
eager_loadings_hash[objects.first].to_a
|
126
|
+
)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
records
|
130
|
+
end
|
131
|
+
|
132
|
+
def construct(ar_parent, parent, row, seen, model_cache, strict_loading_value)
|
133
|
+
if Bullet.start?
|
134
|
+
unless ar_parent.nil?
|
135
|
+
parent.children.each do |node|
|
136
|
+
key = aliases.column_alias(node, node.primary_key)
|
137
|
+
id = row[key]
|
138
|
+
next unless id.nil?
|
139
|
+
|
140
|
+
associations = [node.reflection.name]
|
141
|
+
if node.reflection.through_reflection?
|
142
|
+
associations << node.reflection.through_reflection.name
|
143
|
+
end
|
144
|
+
associations.each do |association|
|
145
|
+
Bullet::Detector::Association.add_object_associations(ar_parent, association)
|
146
|
+
Bullet::Detector::NPlusOneQuery.call_association(ar_parent, association)
|
147
|
+
@bullet_eager_loadings[ar_parent.class] ||= {}
|
148
|
+
@bullet_eager_loadings[ar_parent.class][ar_parent] ||= Set.new
|
149
|
+
@bullet_eager_loadings[ar_parent.class][ar_parent] << association
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
super
|
156
|
+
end
|
157
|
+
|
158
|
+
# call join associations
|
159
|
+
def construct_model(record, node, row, model_cache, id, strict_loading_value)
|
160
|
+
result = super
|
161
|
+
|
162
|
+
if Bullet.start?
|
163
|
+
associations = [node.reflection.name]
|
164
|
+
if node.reflection.through_reflection?
|
165
|
+
associations << node.reflection.through_reflection.name
|
166
|
+
end
|
167
|
+
associations.each do |association|
|
168
|
+
Bullet::Detector::Association.add_object_associations(record, association)
|
169
|
+
Bullet::Detector::NPlusOneQuery.call_association(record, association)
|
170
|
+
@bullet_eager_loadings[record.class] ||= {}
|
171
|
+
@bullet_eager_loadings[record.class][record] ||= Set.new
|
172
|
+
@bullet_eager_loadings[record.class][record] << association
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
result
|
177
|
+
end
|
178
|
+
end
|
179
|
+
)
|
180
|
+
|
181
|
+
::ActiveRecord::Associations::Association.prepend(
|
182
|
+
Module.new do
|
183
|
+
def inversed_from(record)
|
184
|
+
if Bullet.start?
|
185
|
+
Bullet::Detector::NPlusOneQuery.add_inversed_object(owner, reflection.name)
|
186
|
+
end
|
187
|
+
super
|
188
|
+
end
|
189
|
+
|
190
|
+
def inversed_from_queries(record)
|
191
|
+
if Bullet.start? && inversable?(record)
|
192
|
+
Bullet::Detector::NPlusOneQuery.add_inversed_object(owner, reflection.name)
|
193
|
+
end
|
194
|
+
super
|
195
|
+
end
|
196
|
+
end
|
197
|
+
)
|
198
|
+
|
199
|
+
::ActiveRecord::Associations::CollectionAssociation.prepend(
|
200
|
+
Module.new do
|
201
|
+
def load_target
|
202
|
+
records = super
|
203
|
+
|
204
|
+
if Bullet.start?
|
205
|
+
if is_a? ::ActiveRecord::Associations::ThroughAssociation
|
206
|
+
association = owner.association(reflection.through_reflection.name)
|
207
|
+
if association.loaded?
|
208
|
+
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
|
209
|
+
Array.wrap(association.target).each do |through_record|
|
210
|
+
Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
|
211
|
+
end
|
212
|
+
|
213
|
+
if reflection.through_reflection != through_reflection
|
214
|
+
Bullet::Detector::NPlusOneQuery.call_association(owner, through_reflection.name)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
|
219
|
+
if records.first.class.name !~ /^HABTM_/
|
220
|
+
if records.size > 1
|
221
|
+
Bullet::Detector::NPlusOneQuery.add_possible_objects(records)
|
222
|
+
Bullet::Detector::CounterCache.add_possible_objects(records)
|
223
|
+
elsif records.size == 1
|
224
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(records.first)
|
225
|
+
Bullet::Detector::CounterCache.add_impossible_object(records.first)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
records
|
230
|
+
end
|
231
|
+
|
232
|
+
def empty?
|
233
|
+
if Bullet.start? && !reflection.has_cached_counter?
|
234
|
+
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
|
235
|
+
end
|
236
|
+
super
|
237
|
+
end
|
238
|
+
|
239
|
+
def include?(object)
|
240
|
+
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name) if Bullet.start?
|
241
|
+
super
|
242
|
+
end
|
243
|
+
end
|
244
|
+
)
|
245
|
+
|
246
|
+
::ActiveRecord::Associations::SingularAssociation.prepend(
|
247
|
+
Module.new do
|
248
|
+
# call has_one and belongs_to associations
|
249
|
+
def reader
|
250
|
+
result = super
|
251
|
+
|
252
|
+
if Bullet.start?
|
253
|
+
if owner.class.name !~ /^HABTM_/
|
254
|
+
if is_a? ::ActiveRecord::Associations::ThroughAssociation
|
255
|
+
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
|
256
|
+
association = owner.association(reflection.through_reflection.name)
|
257
|
+
Array.wrap(association.target).each do |through_record|
|
258
|
+
Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
|
259
|
+
end
|
260
|
+
|
261
|
+
if reflection.through_reflection != through_reflection
|
262
|
+
Bullet::Detector::NPlusOneQuery.call_association(owner, through_reflection.name)
|
263
|
+
end
|
264
|
+
end
|
265
|
+
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
|
266
|
+
|
267
|
+
if Bullet::Detector::NPlusOneQuery.impossible?(owner)
|
268
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(result) if result
|
269
|
+
else
|
270
|
+
Bullet::Detector::NPlusOneQuery.add_possible_objects(result) if result
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
result
|
275
|
+
end
|
276
|
+
end
|
277
|
+
)
|
278
|
+
|
279
|
+
::ActiveRecord::Associations::HasManyAssociation.prepend(
|
280
|
+
Module.new do
|
281
|
+
def empty?
|
282
|
+
result = super
|
283
|
+
if Bullet.start? && !reflection.has_cached_counter?
|
284
|
+
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
|
285
|
+
end
|
286
|
+
result
|
287
|
+
end
|
288
|
+
|
289
|
+
def count_records
|
290
|
+
result = reflection.has_cached_counter?
|
291
|
+
if Bullet.start? && !result && !is_a?(::ActiveRecord::Associations::ThroughAssociation)
|
292
|
+
Bullet::Detector::CounterCache.add_counter_cache(owner, reflection.name)
|
293
|
+
end
|
294
|
+
super
|
295
|
+
end
|
296
|
+
end
|
297
|
+
)
|
298
|
+
|
299
|
+
::ActiveRecord::Associations::CollectionProxy.prepend(
|
300
|
+
Module.new do
|
301
|
+
def count(column_name = nil)
|
302
|
+
if Bullet.start? && !proxy_association.is_a?(::ActiveRecord::Associations::ThroughAssociation)
|
303
|
+
Bullet::Detector::CounterCache.add_counter_cache(
|
304
|
+
proxy_association.owner,
|
305
|
+
proxy_association.reflection.name
|
306
|
+
)
|
307
|
+
Bullet::Detector::NPlusOneQuery.call_association(
|
308
|
+
proxy_association.owner,
|
309
|
+
proxy_association.reflection.name
|
310
|
+
)
|
311
|
+
end
|
312
|
+
super(column_name)
|
313
|
+
end
|
314
|
+
end
|
315
|
+
)
|
316
|
+
end
|
317
|
+
end
|
318
|
+
end
|
data/lib/bullet/dependency.rb
CHANGED
@@ -33,6 +33,8 @@ module Bullet
|
|
33
33
|
'active_record70'
|
34
34
|
elsif active_record71?
|
35
35
|
'active_record71'
|
36
|
+
elsif active_record72?
|
37
|
+
'active_record72'
|
36
38
|
else
|
37
39
|
raise "Bullet does not support active_record #{::ActiveRecord::VERSION::STRING} yet"
|
38
40
|
end
|
@@ -114,6 +116,10 @@ module Bullet
|
|
114
116
|
active_record7? && ::ActiveRecord::VERSION::MINOR == 1
|
115
117
|
end
|
116
118
|
|
119
|
+
def active_record72?
|
120
|
+
active_record7? && ::ActiveRecord::VERSION::MINOR == 2
|
121
|
+
end
|
122
|
+
|
117
123
|
def mongoid4x?
|
118
124
|
mongoid? && ::Mongoid::VERSION =~ /\A4/
|
119
125
|
end
|
data/lib/bullet/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bullet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 7.
|
4
|
+
version: 7.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Richard Huang
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-07-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -59,6 +59,7 @@ files:
|
|
59
59
|
- lib/bullet/active_record61.rb
|
60
60
|
- lib/bullet/active_record70.rb
|
61
61
|
- lib/bullet/active_record71.rb
|
62
|
+
- lib/bullet/active_record72.rb
|
62
63
|
- lib/bullet/bullet_xhr.js
|
63
64
|
- lib/bullet/dependency.rb
|
64
65
|
- lib/bullet/detector.rb
|
@@ -111,7 +112,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
111
112
|
- !ruby/object:Gem::Version
|
112
113
|
version: 1.3.6
|
113
114
|
requirements: []
|
114
|
-
rubygems_version: 3.5.
|
115
|
+
rubygems_version: 3.5.14
|
115
116
|
signing_key:
|
116
117
|
specification_version: 4
|
117
118
|
summary: help to kill N+1 queries and unused eager loading.
|