bullet 7.1.6 → 7.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 752fed6e96f9ea5c1baefca2e9a80ea3aefa13c279d24688f3341d18c8334afc
4
- data.tar.gz: 78edabbca2c71e9c6d2c793bd3786d5b826f4530664aa18e7cd42cb059a85373
3
+ metadata.gz: a0528fba283865b1a94ba6a82d3f5941c63a62e7b34a08332d6208dfde7f28ba
4
+ data.tar.gz: 21ad1b7a9c1ab8473ddfff4fcd260346b5088a2f8cf615fbe74abfbe2e70c307
5
5
  SHA512:
6
- metadata.gz: 5cad943f3641de44f17da3fe2062ed83525d0bbb1d4321208f55b4d05d6a43840f25fe0728fa4e10f42701dd8ef4eaa2322ca9ab8c8d6a2e7d7067c70d0d3186
7
- data.tar.gz: a58309dcbfaadbb9f67352c0a1730be8397c2522ef403093fcf58a8fdcc596b45e961d39b239e40412d46d98a50033ed02398efc70df4314631bd16e220a7c88
6
+ metadata.gz: 8f6a75db29ab14c89ebd57664f7d96ee5f006fbc816dcbc442678ded0171712aadd360dbb204a567519cab8a49879c067b83a090ea3a8999d212b6801d60fa92
7
+ data.tar.gz: 4b51f257fb70205d068e7f233b0e5e30967da936e19481bd9d956b0303f85b67b95792a00a92f272e04333d3861dd69d6ac916c156d06b5db9f5136e0b543dd9
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  ## Next Release
2
2
 
3
+ ## 7.2.0 (07/12/2024)
4
+
5
+ * Support rails 7.2
6
+ * Fix count method signature for active_record5 and active_record60
7
+
3
8
  ## 7.1.6 (01/16/2024)
4
9
 
5
10
  * Allow apps to not include the user in a notification
@@ -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
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bullet
4
- VERSION = '7.1.6'
4
+ VERSION = '7.2.0'
5
5
  end
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.1.6
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-01-16 00:00:00.000000000 Z
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.3
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.