bullet 7.1.2 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7c62bb5eb8bdfdb62ce49a79609ce7665d6af8be0f7dede7361379597415dcd4
4
- data.tar.gz: 8da00673c07b79eb6dbf7b061aaf6dd0208fd0be841a96c3169ba919259fcf82
3
+ metadata.gz: a0528fba283865b1a94ba6a82d3f5941c63a62e7b34a08332d6208dfde7f28ba
4
+ data.tar.gz: 21ad1b7a9c1ab8473ddfff4fcd260346b5088a2f8cf615fbe74abfbe2e70c307
5
5
  SHA512:
6
- metadata.gz: f33ad269a72ba293680c65ed460ef4e598446eebf62c82d79879de03b3cb52098f27499cab681facec3fdc3a3d6f937d064c21621aefcc69edcf499a52680838
7
- data.tar.gz: 4a386c2bda2cdea90926ce9ff8bca0932954507ac4fa1e5986a356d869c3fb410b48708a5de843fb0e1f822f744ef1cf26dcecc9036ad3036f774ffad1c6e84e
6
+ metadata.gz: 8f6a75db29ab14c89ebd57664f7d96ee5f006fbc816dcbc442678ded0171712aadd360dbb204a567519cab8a49879c067b83a090ea3a8999d212b6801d60fa92
7
+ data.tar.gz: 4b51f257fb70205d068e7f233b0e5e30967da936e19481bd9d956b0303f85b67b95792a00a92f272e04333d3861dd69d6ac916c156d06b5db9f5136e0b543dd9
data/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
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
+
8
+ ## 7.1.6 (01/16/2024)
9
+
10
+ * Allow apps to not include the user in a notification
11
+
12
+ ## 7.1.5 (01/05/2024)
13
+
14
+ * Fix mongoid8
15
+
16
+ ## 7.1.4 (11/17/2023)
17
+
18
+ * Call association also on through reflection
19
+
20
+ ## 7.1.3 (11/05/2023)
21
+
22
+ * Call NPlusOneQuery's call_association when calling count on collection association
23
+
3
24
  ## 7.1.2 (10/13/2023)
4
25
 
5
26
  * Handle Rails 7.1 composite primary keys
@@ -256,7 +277,7 @@
256
277
 
257
278
  ## 4.5.0 (03/24/2013)
258
279
 
259
- * Add api way to access captured associatioin
280
+ * Add api way to access captured association
260
281
  * Allow disable n_plus_one_query, unused_eager_loading and counter_cache respectively
261
282
  * Add whitelist
262
283
 
data/README.md CHANGED
@@ -102,6 +102,7 @@ The code above will enable all of the Bullet notification systems:
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
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.
105
+ * `Bullet.skip_user_in_notification`: exclude the OS user (`whoami`) from notifications.
105
106
 
106
107
 
107
108
  Bullet also allows you to disable any of its detectors.
@@ -287,17 +288,17 @@ $ rails new test_bullet
287
288
  $ cd test_bullet
288
289
  $ rails g scaffold post name:string
289
290
  $ rails g scaffold comment name:string post_id:integer
290
- $ bundle exec rake db:migrate
291
+ $ bundle exec rails db:migrate
291
292
  ```
292
293
 
293
294
  2\. Change `app/models/post.rb` and `app/models/comment.rb`
294
295
 
295
296
  ```ruby
296
- class Post < ActiveRecord::Base
297
+ class Post < ApplicationRecord
297
298
  has_many :comments
298
299
  end
299
300
 
300
- class Comment < ActiveRecord::Base
301
+ class Comment < ApplicationRecord
301
302
  belongs_to :post
302
303
  end
303
304
  ```
@@ -107,12 +107,17 @@ module Bullet
107
107
  result = origin_construct_association(record, join, row)
108
108
 
109
109
  if Bullet.start?
110
- associations = join.reflection.name
111
- Bullet::Detector::Association.add_object_associations(record, associations)
112
- Bullet::Detector::NPlusOneQuery.call_association(record, associations)
113
- @bullet_eager_loadings[record.class] ||= {}
114
- @bullet_eager_loadings[record.class][record] ||= Set.new
115
- @bullet_eager_loadings[record.class][record] << associations
110
+ associations = [join.reflection.name]
111
+ if join.reflection.nested?
112
+ associations << join.reflection.through_reflection.name
113
+ end
114
+ associations.each do |association|
115
+ Bullet::Detector::Association.add_object_associations(record, association)
116
+ Bullet::Detector::NPlusOneQuery.call_association(record, association)
117
+ @bullet_eager_loadings[record.class] ||= {}
118
+ @bullet_eager_loadings[record.class][record] ||= Set.new
119
+ @bullet_eager_loadings[record.class][record] << association
120
+ end
116
121
  end
117
122
 
118
123
  result
@@ -181,6 +186,7 @@ module Bullet
181
186
  def count(column_name = nil, options = {})
182
187
  if Bullet.start?
183
188
  Bullet::Detector::CounterCache.add_counter_cache(proxy_association.owner, proxy_association.reflection.name)
189
+ Bullet::Detector::NPlusOneQuery.call_association(proxy_association.owner, proxy_association.reflection.name)
184
190
  end
185
191
  super(column_name, options)
186
192
  end
@@ -110,12 +110,17 @@ module Bullet
110
110
  result = origin_construct_model(record, node, row, model_cache, id, aliases)
111
111
 
112
112
  if Bullet.start?
113
- associations = node.reflection.name
114
- Bullet::Detector::Association.add_object_associations(record, associations)
115
- Bullet::Detector::NPlusOneQuery.call_association(record, associations)
116
- @bullet_eager_loadings[record.class] ||= {}
117
- @bullet_eager_loadings[record.class][record] ||= Set.new
118
- @bullet_eager_loadings[record.class][record] << associations
113
+ associations = [node.reflection.name]
114
+ if node.reflection.nested?
115
+ associations << node.reflection.through_reflection.name
116
+ end
117
+ associations.each do |association|
118
+ Bullet::Detector::Association.add_object_associations(record, association)
119
+ Bullet::Detector::NPlusOneQuery.call_association(record, association)
120
+ @bullet_eager_loadings[record.class] ||= {}
121
+ @bullet_eager_loadings[record.class][record] ||= Set.new
122
+ @bullet_eager_loadings[record.class][record] << association
123
+ end
119
124
  end
120
125
 
121
126
  result
@@ -173,6 +178,7 @@ module Bullet
173
178
  def count(column_name = nil, options = {})
174
179
  if Bullet.start?
175
180
  Bullet::Detector::CounterCache.add_counter_cache(proxy_association.owner, proxy_association.reflection.name)
181
+ Bullet::Detector::NPlusOneQuery.call_association(proxy_association.owner, proxy_association.reflection.name)
176
182
  end
177
183
  super(column_name, options)
178
184
  end
@@ -129,12 +129,17 @@ module Bullet
129
129
  id = row[key]
130
130
  next unless id.nil?
131
131
 
132
- associations = node.reflection.name
133
- Bullet::Detector::Association.add_object_associations(ar_parent, associations)
134
- Bullet::Detector::NPlusOneQuery.call_association(ar_parent, associations)
135
- @bullet_eager_loadings[ar_parent.class] ||= {}
136
- @bullet_eager_loadings[ar_parent.class][ar_parent] ||= Set.new
137
- @bullet_eager_loadings[ar_parent.class][ar_parent] << associations
132
+ associations = [node.reflection.name]
133
+ if node.reflection.nested?
134
+ associations << node.reflection.through_reflection.name
135
+ end
136
+ associations.each do |association|
137
+ Bullet::Detector::Association.add_object_associations(ar_parent, association)
138
+ Bullet::Detector::NPlusOneQuery.call_association(ar_parent, association)
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] << association
142
+ end
138
143
  end
139
144
  end
140
145
  end
@@ -147,12 +152,17 @@ module Bullet
147
152
  result = origin_construct_model(record, node, row, model_cache, id, aliases)
148
153
 
149
154
  if Bullet.start?
150
- associations = node.reflection.name
151
- Bullet::Detector::Association.add_object_associations(record, associations)
152
- Bullet::Detector::NPlusOneQuery.call_association(record, associations)
153
- @bullet_eager_loadings[record.class] ||= {}
154
- @bullet_eager_loadings[record.class][record] ||= Set.new
155
- @bullet_eager_loadings[record.class][record] << associations
155
+ associations = [node.reflection.name]
156
+ if node.reflection.nested?
157
+ associations << node.reflection.through_reflection.name
158
+ end
159
+ associations.each do |association|
160
+ Bullet::Detector::Association.add_object_associations(record, association)
161
+ Bullet::Detector::NPlusOneQuery.call_association(record, association)
162
+ @bullet_eager_loadings[record.class] ||= {}
163
+ @bullet_eager_loadings[record.class][record] ||= Set.new
164
+ @bullet_eager_loadings[record.class][record] << association
165
+ end
156
166
  end
157
167
 
158
168
  result
@@ -238,6 +248,7 @@ module Bullet
238
248
  def count(column_name = nil, options = {})
239
249
  if Bullet.start?
240
250
  Bullet::Detector::CounterCache.add_counter_cache(proxy_association.owner, proxy_association.reflection.name)
251
+ Bullet::Detector::NPlusOneQuery.call_association(proxy_association.owner, proxy_association.reflection.name)
241
252
  end
242
253
  super(column_name, options)
243
254
  end
@@ -138,12 +138,17 @@ module Bullet
138
138
  id = row[key]
139
139
  next unless id.nil?
140
140
 
141
- associations = node.reflection.name
142
- Bullet::Detector::Association.add_object_associations(ar_parent, associations)
143
- Bullet::Detector::NPlusOneQuery.call_association(ar_parent, associations)
144
- @bullet_eager_loadings[ar_parent.class] ||= {}
145
- @bullet_eager_loadings[ar_parent.class][ar_parent] ||= Set.new
146
- @bullet_eager_loadings[ar_parent.class][ar_parent] << associations
141
+ associations = [node.reflection.name]
142
+ if node.reflection.through_reflection?
143
+ associations << node.reflection.through_reflection.name
144
+ end
145
+ associations.each do |association|
146
+ Bullet::Detector::Association.add_object_associations(ar_parent, association)
147
+ Bullet::Detector::NPlusOneQuery.call_association(ar_parent, association)
148
+ @bullet_eager_loadings[ar_parent.class] ||= {}
149
+ @bullet_eager_loadings[ar_parent.class][ar_parent] ||= Set.new
150
+ @bullet_eager_loadings[ar_parent.class][ar_parent] << association
151
+ end
147
152
  end
148
153
  end
149
154
  end
@@ -156,12 +161,17 @@ module Bullet
156
161
  result = super
157
162
 
158
163
  if Bullet.start?
159
- associations = node.reflection.name
160
- Bullet::Detector::Association.add_object_associations(record, associations)
161
- Bullet::Detector::NPlusOneQuery.call_association(record, associations)
162
- @bullet_eager_loadings[record.class] ||= {}
163
- @bullet_eager_loadings[record.class][record] ||= Set.new
164
- @bullet_eager_loadings[record.class][record] << associations
164
+ associations = [node.reflection.name]
165
+ if node.reflection.through_reflection?
166
+ associations << node.reflection.through_reflection.name
167
+ end
168
+ associations.each do |association|
169
+ Bullet::Detector::Association.add_object_associations(record, association)
170
+ Bullet::Detector::NPlusOneQuery.call_association(record, association)
171
+ @bullet_eager_loadings[record.class] ||= {}
172
+ @bullet_eager_loadings[record.class][record] ||= Set.new
173
+ @bullet_eager_loadings[record.class][record] << association
174
+ end
165
175
  end
166
176
 
167
177
  result
@@ -263,14 +273,18 @@ module Bullet
263
273
 
264
274
  ::ActiveRecord::Associations::CollectionProxy.prepend(
265
275
  Module.new do
266
- def count
276
+ def count(column_name = nil)
267
277
  if Bullet.start? && !proxy_association.is_a?(::ActiveRecord::Associations::ThroughAssociation)
268
278
  Bullet::Detector::CounterCache.add_counter_cache(
269
279
  proxy_association.owner,
270
280
  proxy_association.reflection.name
271
281
  )
282
+ Bullet::Detector::NPlusOneQuery.call_association(
283
+ proxy_association.owner,
284
+ proxy_association.reflection.name
285
+ )
272
286
  end
273
- super
287
+ super(column_name)
274
288
  end
275
289
  end
276
290
  )
@@ -101,12 +101,17 @@ module Bullet
101
101
  id = row[key]
102
102
  next unless id.nil?
103
103
 
104
- associations = node.reflection.name
105
- Bullet::Detector::Association.add_object_associations(ar_parent, associations)
106
- Bullet::Detector::NPlusOneQuery.call_association(ar_parent, associations)
107
- @bullet_eager_loadings[ar_parent.class] ||= {}
108
- @bullet_eager_loadings[ar_parent.class][ar_parent] ||= Set.new
109
- @bullet_eager_loadings[ar_parent.class][ar_parent] << associations
104
+ associations = [node.reflection.name]
105
+ if node.reflection.through_reflection?
106
+ associations << node.reflection.through_reflection.name
107
+ end
108
+ associations.each do |association|
109
+ Bullet::Detector::Association.add_object_associations(ar_parent, association)
110
+ Bullet::Detector::NPlusOneQuery.call_association(ar_parent, association)
111
+ @bullet_eager_loadings[ar_parent.class] ||= {}
112
+ @bullet_eager_loadings[ar_parent.class][ar_parent] ||= Set.new
113
+ @bullet_eager_loadings[ar_parent.class][ar_parent] << association
114
+ end
110
115
  end
111
116
  end
112
117
  end
@@ -119,12 +124,17 @@ module Bullet
119
124
  result = super
120
125
 
121
126
  if Bullet.start?
122
- associations = node.reflection.name
123
- Bullet::Detector::Association.add_object_associations(record, associations)
124
- Bullet::Detector::NPlusOneQuery.call_association(record, associations)
125
- @bullet_eager_loadings[record.class] ||= {}
126
- @bullet_eager_loadings[record.class][record] ||= Set.new
127
- @bullet_eager_loadings[record.class][record] << associations
127
+ associations = [node.reflection.name]
128
+ if node.reflection.through_reflection?
129
+ associations << node.reflection.through_reflection.name
130
+ end
131
+ associations.each do |association|
132
+ Bullet::Detector::Association.add_object_associations(record, association)
133
+ Bullet::Detector::NPlusOneQuery.call_association(record, association)
134
+ @bullet_eager_loadings[record.class] ||= {}
135
+ @bullet_eager_loadings[record.class][record] ||= Set.new
136
+ @bullet_eager_loadings[record.class][record] << association
137
+ end
128
138
  end
129
139
 
130
140
  result
@@ -251,6 +261,10 @@ module Bullet
251
261
  proxy_association.owner,
252
262
  proxy_association.reflection.name
253
263
  )
264
+ Bullet::Detector::NPlusOneQuery.call_association(
265
+ proxy_association.owner,
266
+ proxy_association.reflection.name
267
+ )
254
268
  end
255
269
  super(column_name)
256
270
  end
@@ -128,12 +128,17 @@ module Bullet
128
128
  id = row[key]
129
129
  next unless id.nil?
130
130
 
131
- associations = node.reflection.name
132
- Bullet::Detector::Association.add_object_associations(ar_parent, associations)
133
- Bullet::Detector::NPlusOneQuery.call_association(ar_parent, associations)
134
- @bullet_eager_loadings[ar_parent.class] ||= {}
135
- @bullet_eager_loadings[ar_parent.class][ar_parent] ||= Set.new
136
- @bullet_eager_loadings[ar_parent.class][ar_parent] << associations
131
+ associations = [node.reflection.name]
132
+ if node.reflection.through_reflection?
133
+ associations << node.reflection.through_reflection.name
134
+ end
135
+ associations.each do |association|
136
+ Bullet::Detector::Association.add_object_associations(ar_parent, association)
137
+ Bullet::Detector::NPlusOneQuery.call_association(ar_parent, association)
138
+ @bullet_eager_loadings[ar_parent.class] ||= {}
139
+ @bullet_eager_loadings[ar_parent.class][ar_parent] ||= Set.new
140
+ @bullet_eager_loadings[ar_parent.class][ar_parent] << association
141
+ end
137
142
  end
138
143
  end
139
144
  end
@@ -146,12 +151,17 @@ module Bullet
146
151
  result = super
147
152
 
148
153
  if Bullet.start?
149
- associations = node.reflection.name
150
- Bullet::Detector::Association.add_object_associations(record, associations)
151
- Bullet::Detector::NPlusOneQuery.call_association(record, associations)
152
- @bullet_eager_loadings[record.class] ||= {}
153
- @bullet_eager_loadings[record.class][record] ||= Set.new
154
- @bullet_eager_loadings[record.class][record] << associations
154
+ associations = [node.reflection.name]
155
+ if node.reflection.through_reflection?
156
+ associations << node.reflection.through_reflection.name
157
+ end
158
+ associations.each do |association|
159
+ Bullet::Detector::Association.add_object_associations(record, association)
160
+ Bullet::Detector::NPlusOneQuery.call_association(record, association)
161
+ @bullet_eager_loadings[record.class] ||= {}
162
+ @bullet_eager_loadings[record.class][record] ||= Set.new
163
+ @bullet_eager_loadings[record.class][record] << association
164
+ end
155
165
  end
156
166
 
157
167
  result
@@ -272,14 +282,18 @@ module Bullet
272
282
 
273
283
  ::ActiveRecord::Associations::CollectionProxy.prepend(
274
284
  Module.new do
275
- def count
285
+ def count(column_name = nil)
276
286
  if Bullet.start? && !proxy_association.is_a?(::ActiveRecord::Associations::ThroughAssociation)
277
287
  Bullet::Detector::CounterCache.add_counter_cache(
278
288
  proxy_association.owner,
279
289
  proxy_association.reflection.name
280
290
  )
291
+ Bullet::Detector::NPlusOneQuery.call_association(
292
+ proxy_association.owner,
293
+ proxy_association.reflection.name
294
+ )
281
295
  end
282
- super
296
+ super(column_name)
283
297
  end
284
298
  end
285
299
  )
@@ -128,12 +128,17 @@ module Bullet
128
128
  id = row[key]
129
129
  next unless id.nil?
130
130
 
131
- associations = node.reflection.name
132
- Bullet::Detector::Association.add_object_associations(ar_parent, associations)
133
- Bullet::Detector::NPlusOneQuery.call_association(ar_parent, associations)
134
- @bullet_eager_loadings[ar_parent.class] ||= {}
135
- @bullet_eager_loadings[ar_parent.class][ar_parent] ||= Set.new
136
- @bullet_eager_loadings[ar_parent.class][ar_parent] << associations
131
+ associations = [node.reflection.name]
132
+ if node.reflection.through_reflection?
133
+ associations << node.reflection.through_reflection.name
134
+ end
135
+ associations.each do |association|
136
+ Bullet::Detector::Association.add_object_associations(ar_parent, association)
137
+ Bullet::Detector::NPlusOneQuery.call_association(ar_parent, association)
138
+ @bullet_eager_loadings[ar_parent.class] ||= {}
139
+ @bullet_eager_loadings[ar_parent.class][ar_parent] ||= Set.new
140
+ @bullet_eager_loadings[ar_parent.class][ar_parent] << association
141
+ end
137
142
  end
138
143
  end
139
144
  end
@@ -146,12 +151,17 @@ module Bullet
146
151
  result = super
147
152
 
148
153
  if Bullet.start?
149
- associations = node.reflection.name
150
- Bullet::Detector::Association.add_object_associations(record, associations)
151
- Bullet::Detector::NPlusOneQuery.call_association(record, associations)
152
- @bullet_eager_loadings[record.class] ||= {}
153
- @bullet_eager_loadings[record.class][record] ||= Set.new
154
- @bullet_eager_loadings[record.class][record] << associations
154
+ associations = [node.reflection.name]
155
+ if node.reflection.through_reflection?
156
+ associations << node.reflection.through_reflection.name
157
+ end
158
+ associations.each do |association|
159
+ Bullet::Detector::Association.add_object_associations(record, association)
160
+ Bullet::Detector::NPlusOneQuery.call_association(record, association)
161
+ @bullet_eager_loadings[record.class] ||= {}
162
+ @bullet_eager_loadings[record.class][record] ||= Set.new
163
+ @bullet_eager_loadings[record.class][record] << association
164
+ end
155
165
  end
156
166
 
157
167
  result
@@ -278,6 +288,10 @@ module Bullet
278
288
  proxy_association.owner,
279
289
  proxy_association.reflection.name
280
290
  )
291
+ Bullet::Detector::NPlusOneQuery.call_association(
292
+ proxy_association.owner,
293
+ proxy_association.reflection.name
294
+ )
281
295
  end
282
296
  super(column_name)
283
297
  end
@@ -137,12 +137,17 @@ module Bullet
137
137
  id = row[key]
138
138
  next unless id.nil?
139
139
 
140
- associations = node.reflection.name
141
- Bullet::Detector::Association.add_object_associations(ar_parent, associations)
142
- Bullet::Detector::NPlusOneQuery.call_association(ar_parent, associations)
143
- @bullet_eager_loadings[ar_parent.class] ||= {}
144
- @bullet_eager_loadings[ar_parent.class][ar_parent] ||= Set.new
145
- @bullet_eager_loadings[ar_parent.class][ar_parent] << associations
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
146
151
  end
147
152
  end
148
153
  end
@@ -155,12 +160,17 @@ module Bullet
155
160
  result = super
156
161
 
157
162
  if Bullet.start?
158
- associations = node.reflection.name
159
- Bullet::Detector::Association.add_object_associations(record, associations)
160
- Bullet::Detector::NPlusOneQuery.call_association(record, associations)
161
- @bullet_eager_loadings[record.class] ||= {}
162
- @bullet_eager_loadings[record.class][record] ||= Set.new
163
- @bullet_eager_loadings[record.class][record] << associations
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
164
174
  end
165
175
 
166
176
  result
@@ -294,6 +304,10 @@ module Bullet
294
304
  proxy_association.owner,
295
305
  proxy_association.reflection.name
296
306
  )
307
+ Bullet::Detector::NPlusOneQuery.call_association(
308
+ proxy_association.owner,
309
+ proxy_association.reflection.name
310
+ )
297
311
  end
298
312
  super(column_name)
299
313
  end
@@ -137,12 +137,17 @@ module Bullet
137
137
  id = row[key]
138
138
  next unless id.nil?
139
139
 
140
- associations = node.reflection.name
141
- Bullet::Detector::Association.add_object_associations(ar_parent, associations)
142
- Bullet::Detector::NPlusOneQuery.call_association(ar_parent, associations)
143
- @bullet_eager_loadings[ar_parent.class] ||= {}
144
- @bullet_eager_loadings[ar_parent.class][ar_parent] ||= Set.new
145
- @bullet_eager_loadings[ar_parent.class][ar_parent] << associations
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
146
151
  end
147
152
  end
148
153
  end
@@ -155,12 +160,17 @@ module Bullet
155
160
  result = super
156
161
 
157
162
  if Bullet.start?
158
- associations = node.reflection.name
159
- Bullet::Detector::Association.add_object_associations(record, associations)
160
- Bullet::Detector::NPlusOneQuery.call_association(record, associations)
161
- @bullet_eager_loadings[record.class] ||= {}
162
- @bullet_eager_loadings[record.class][record] ||= Set.new
163
- @bullet_eager_loadings[record.class][record] << associations
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
164
174
  end
165
175
 
166
176
  result
@@ -294,6 +304,10 @@ module Bullet
294
304
  proxy_association.owner,
295
305
  proxy_association.reflection.name
296
306
  )
307
+ Bullet::Detector::NPlusOneQuery.call_association(
308
+ proxy_association.owner,
309
+ proxy_association.reflection.name
310
+ )
297
311
  end
298
312
  super(column_name)
299
313
  end
@@ -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
@@ -24,6 +24,7 @@ class Object
24
24
  def bullet_join_potential_composite_primary_key(primary_keys)
25
25
  return send(primary_keys) unless primary_keys.is_a?(Enumerable)
26
26
 
27
- primary_keys.map { |primary_key| send primary_key }.join(',')
27
+ primary_keys.map { |primary_key| send primary_key }
28
+ .join(',')
28
29
  end
29
30
  end
@@ -8,14 +8,14 @@ module Bullet
8
8
  alias_method :origin_each, :each
9
9
  alias_method :origin_eager_load, :eager_load
10
10
 
11
- def first(opts = {})
12
- result = origin_first(opts)
11
+ def first(limit = nil)
12
+ result = origin_first(limit)
13
13
  Bullet::Detector::NPlusOneQuery.add_impossible_object(result) if result
14
14
  result
15
15
  end
16
16
 
17
- def last(opts = {})
18
- result = origin_last(opts)
17
+ def last(limit = nil)
18
+ result = origin_last(limit)
19
19
  Bullet::Detector::NPlusOneQuery.add_impossible_object(result) if result
20
20
  result
21
21
  end
@@ -51,11 +51,22 @@ module Bullet
51
51
  end
52
52
 
53
53
  def short_notice
54
- [whoami.presence, url, title, body].compact.join(' ')
54
+ parts = []
55
+ parts << whoami.presence unless Bullet.skip_user_in_notification
56
+ parts << url
57
+ parts << title
58
+ parts << body
59
+
60
+ parts.compact.join(' ')
55
61
  end
56
62
 
57
63
  def notification_data
58
- { user: whoami, url: url, title: title, body: body_with_caller }
64
+ hash = {}
65
+ hash[:user] = whoami unless Bullet.skip_user_in_notification
66
+ hash[:url] = url
67
+ hash[:title] = title
68
+ hash[:body] = body_with_caller
69
+ hash
59
70
  end
60
71
 
61
72
  def eql?(other)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bullet
4
- VERSION = '7.1.2'
4
+ VERSION = '7.2.0'
5
5
  end
data/lib/bullet.rb CHANGED
@@ -40,7 +40,11 @@ module Bullet
40
40
  :stacktrace_excludes,
41
41
  :skip_html_injection
42
42
  attr_reader :safelist
43
- attr_accessor :add_footer, :orm_patches_applied, :skip_http_headers, :always_append_html_body
43
+ attr_accessor :add_footer,
44
+ :orm_patches_applied,
45
+ :skip_http_headers,
46
+ :always_append_html_body,
47
+ :skip_user_in_notification
44
48
 
45
49
  available_notifiers =
46
50
  UniformNotifier::AVAILABLE_NOTIFIERS.select { |notifier| notifier != :raise }
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.2
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: 2023-10-13 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.4.20
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.