hyper-pure-sys 0.0.1

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.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/bullet-8.1.3/CHANGELOG.md +374 -0
  3. data/bullet-8.1.3/MIT-LICENSE +20 -0
  4. data/bullet-8.1.3/README.md +525 -0
  5. data/bullet-8.1.3/lib/bullet/active_job.rb +13 -0
  6. data/bullet-8.1.3/lib/bullet/active_record4.rb +197 -0
  7. data/bullet-8.1.3/lib/bullet/active_record41.rb +191 -0
  8. data/bullet-8.1.3/lib/bullet/active_record42.rb +262 -0
  9. data/bullet-8.1.3/lib/bullet/active_record5.rb +294 -0
  10. data/bullet-8.1.3/lib/bullet/active_record52.rb +278 -0
  11. data/bullet-8.1.3/lib/bullet/active_record60.rb +310 -0
  12. data/bullet-8.1.3/lib/bullet/active_record61.rb +310 -0
  13. data/bullet-8.1.3/lib/bullet/active_record70.rb +319 -0
  14. data/bullet-8.1.3/lib/bullet/active_record71.rb +319 -0
  15. data/bullet-8.1.3/lib/bullet/active_record72.rb +319 -0
  16. data/bullet-8.1.3/lib/bullet/active_record80.rb +319 -0
  17. data/bullet-8.1.3/lib/bullet/active_record81.rb +321 -0
  18. data/bullet-8.1.3/lib/bullet/bullet_xhr.js +64 -0
  19. data/bullet-8.1.3/lib/bullet/dependency.rb +165 -0
  20. data/bullet-8.1.3/lib/bullet/detector/association.rb +92 -0
  21. data/bullet-8.1.3/lib/bullet/detector/base.rb +8 -0
  22. data/bullet-8.1.3/lib/bullet/detector/counter_cache.rb +69 -0
  23. data/bullet-8.1.3/lib/bullet/detector/n_plus_one_query.rb +148 -0
  24. data/bullet-8.1.3/lib/bullet/detector/unused_eager_loading.rb +100 -0
  25. data/bullet-8.1.3/lib/bullet/detector.rb +11 -0
  26. data/bullet-8.1.3/lib/bullet/ext/object.rb +37 -0
  27. data/bullet-8.1.3/lib/bullet/ext/string.rb +14 -0
  28. data/bullet-8.1.3/lib/bullet/mongoid4x.rb +59 -0
  29. data/bullet-8.1.3/lib/bullet/mongoid5x.rb +59 -0
  30. data/bullet-8.1.3/lib/bullet/mongoid6x.rb +59 -0
  31. data/bullet-8.1.3/lib/bullet/mongoid7x.rb +74 -0
  32. data/bullet-8.1.3/lib/bullet/mongoid8x.rb +61 -0
  33. data/bullet-8.1.3/lib/bullet/mongoid9x.rb +74 -0
  34. data/bullet-8.1.3/lib/bullet/notification/base.rb +92 -0
  35. data/bullet-8.1.3/lib/bullet/notification/counter_cache.rb +15 -0
  36. data/bullet-8.1.3/lib/bullet/notification/n_plus_one_query.rb +31 -0
  37. data/bullet-8.1.3/lib/bullet/notification/unused_eager_loading.rb +31 -0
  38. data/bullet-8.1.3/lib/bullet/notification.rb +13 -0
  39. data/bullet-8.1.3/lib/bullet/notification_collector.rb +25 -0
  40. data/bullet-8.1.3/lib/bullet/rack.rb +186 -0
  41. data/bullet-8.1.3/lib/bullet/registry/association.rb +16 -0
  42. data/bullet-8.1.3/lib/bullet/registry/base.rb +46 -0
  43. data/bullet-8.1.3/lib/bullet/registry/call_stack.rb +17 -0
  44. data/bullet-8.1.3/lib/bullet/registry/object.rb +18 -0
  45. data/bullet-8.1.3/lib/bullet/registry.rb +10 -0
  46. data/bullet-8.1.3/lib/bullet/stack_trace_filter.rb +67 -0
  47. data/bullet-8.1.3/lib/bullet/version.rb +5 -0
  48. data/bullet-8.1.3/lib/bullet.rb +289 -0
  49. data/bullet-8.1.3/lib/generators/bullet/install_generator.rb +47 -0
  50. data/bullet-8.1.3/tasks/bullet_tasks.rake +11 -0
  51. data/hyper-pure-sys.gemspec +12 -0
  52. metadata +91 -0
@@ -0,0 +1,319 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bullet
4
+ module SaveWithBulletSupport
5
+ def _create_record(*)
6
+ super do
7
+ Bullet::Detector::NPlusOneQuery.update_inversed_object(self)
8
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(self)
9
+ yield(self) if block_given?
10
+ end
11
+ end
12
+ end
13
+
14
+ module ActiveRecord
15
+ def self.enable
16
+ require 'active_record'
17
+ ::ActiveRecord::Base.extend(
18
+ Module.new do
19
+ def find_by_sql(sql, binds = [], preparable: nil, &block)
20
+ result = super
21
+ if Bullet.start?
22
+ if result.is_a? Array
23
+ if result.size > 1
24
+ Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
25
+ Bullet::Detector::CounterCache.add_possible_objects(result)
26
+ elsif result.size == 1
27
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(result.first)
28
+ Bullet::Detector::CounterCache.add_impossible_object(result.first)
29
+ end
30
+ elsif result.is_a? ::ActiveRecord::Base
31
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(result)
32
+ Bullet::Detector::CounterCache.add_impossible_object(result)
33
+ end
34
+ end
35
+ result
36
+ end
37
+ end
38
+ )
39
+
40
+ ::ActiveRecord::Base.prepend(SaveWithBulletSupport)
41
+
42
+ ::ActiveRecord::Relation.prepend(
43
+ Module.new do
44
+ # if select a collection of objects, then these objects have possible to cause N+1 query.
45
+ # if select only one object, then the only one object has impossible to cause N+1 query.
46
+ def records
47
+ result = super
48
+ if Bullet.start?
49
+ if result.first.class.name !~ /^HABTM_/
50
+ if result.size > 1
51
+ Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
52
+ Bullet::Detector::CounterCache.add_possible_objects(result)
53
+ elsif result.size == 1
54
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(result.first)
55
+ Bullet::Detector::CounterCache.add_impossible_object(result.first)
56
+ end
57
+ end
58
+ end
59
+ result
60
+ end
61
+ end
62
+ )
63
+
64
+ ::ActiveRecord::Associations::Preloader::Batch.prepend(
65
+ Module.new do
66
+ def call
67
+ if Bullet.start?
68
+ @preloaders.each do |preloader|
69
+ preloader.records.each { |record|
70
+ Bullet::Detector::Association.add_object_associations(record, preloader.associations)
71
+ }
72
+ Bullet::Detector::UnusedEagerLoading.add_eager_loadings(preloader.records, preloader.associations)
73
+ end
74
+ end
75
+ super
76
+ end
77
+ end
78
+ )
79
+
80
+ ::ActiveRecord::Associations::Preloader::Branch.prepend(
81
+ Module.new do
82
+ def preloaders_for_reflection(reflection, reflection_records)
83
+ if Bullet.start?
84
+ reflection_records.compact!
85
+ if reflection_records.first.class.name !~ /^HABTM_/
86
+ reflection_records.each { |record|
87
+ Bullet::Detector::Association.add_object_associations(record, reflection.name)
88
+ }
89
+ Bullet::Detector::UnusedEagerLoading.add_eager_loadings(reflection_records, reflection.name)
90
+ end
91
+ end
92
+ super
93
+ end
94
+ end
95
+ )
96
+
97
+ ::ActiveRecord::Associations::Preloader::ThroughAssociation.prepend(
98
+ Module.new do
99
+ def source_preloaders
100
+ if Bullet.start? && !defined?(@source_preloaders)
101
+ preloaders = super
102
+ preloaders.each do |preloader|
103
+ reflection_name = preloader.send(:reflection).name
104
+ preloader.send(:owners).each do |owner|
105
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection_name)
106
+ end
107
+ end
108
+ else
109
+ super
110
+ end
111
+ end
112
+ end
113
+ )
114
+
115
+ ::ActiveRecord::Associations::JoinDependency.prepend(
116
+ Module.new do
117
+ def instantiate(result_set, strict_loading_value, &block)
118
+ @bullet_eager_loadings = {}
119
+ records = super
120
+
121
+ if Bullet.start?
122
+ @bullet_eager_loadings.each do |_klazz, eager_loadings_hash|
123
+ objects = eager_loadings_hash.keys
124
+ Bullet::Detector::UnusedEagerLoading.add_eager_loadings(
125
+ objects,
126
+ eager_loadings_hash[objects.first].to_a
127
+ )
128
+ end
129
+ end
130
+ records
131
+ end
132
+
133
+ def construct(ar_parent, parent, row, seen, model_cache, strict_loading_value)
134
+ if Bullet.start?
135
+ unless ar_parent.nil?
136
+ parent.children.each do |node|
137
+ key = aliases.column_alias(node, node.primary_key)
138
+ id = row[key]
139
+ next unless id.nil?
140
+
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
152
+ end
153
+ end
154
+ end
155
+
156
+ super
157
+ end
158
+
159
+ # call join associations
160
+ def construct_model(record, node, row, model_cache, id, strict_loading_value)
161
+ result = super
162
+
163
+ if Bullet.start?
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
175
+ end
176
+
177
+ result
178
+ end
179
+ end
180
+ )
181
+
182
+ ::ActiveRecord::Associations::Association.prepend(
183
+ Module.new do
184
+ def inversed_from(record)
185
+ if Bullet.start?
186
+ Bullet::Detector::NPlusOneQuery.add_inversed_object(owner, reflection.name)
187
+ end
188
+ super
189
+ end
190
+
191
+ def inversed_from_queries(record)
192
+ if Bullet.start? && inversable?(record)
193
+ Bullet::Detector::NPlusOneQuery.add_inversed_object(owner, reflection.name)
194
+ end
195
+ super
196
+ end
197
+ end
198
+ )
199
+
200
+ ::ActiveRecord::Associations::CollectionAssociation.prepend(
201
+ Module.new do
202
+ def load_target
203
+ records = super
204
+
205
+ if Bullet.start?
206
+ if is_a? ::ActiveRecord::Associations::ThroughAssociation
207
+ association = owner.association(reflection.through_reflection.name)
208
+ if association.loaded?
209
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
210
+ Array.wrap(association.target).each do |through_record|
211
+ Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
212
+ end
213
+
214
+ if reflection.through_reflection != through_reflection
215
+ Bullet::Detector::NPlusOneQuery.call_association(owner, through_reflection.name)
216
+ end
217
+ end
218
+ end
219
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
220
+ if records.first.class.name !~ /^HABTM_/
221
+ if records.size > 1
222
+ Bullet::Detector::NPlusOneQuery.add_possible_objects(records)
223
+ Bullet::Detector::CounterCache.add_possible_objects(records)
224
+ elsif records.size == 1
225
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(records.first)
226
+ Bullet::Detector::CounterCache.add_impossible_object(records.first)
227
+ end
228
+ end
229
+ end
230
+ records
231
+ end
232
+
233
+ def empty?
234
+ if Bullet.start? && !reflection.has_cached_counter?
235
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name, caller_locations)
236
+ end
237
+ super
238
+ end
239
+
240
+ def include?(object)
241
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name, caller_locations) if Bullet.start?
242
+ super
243
+ end
244
+ end
245
+ )
246
+
247
+ ::ActiveRecord::Associations::SingularAssociation.prepend(
248
+ Module.new do
249
+ # call has_one and belongs_to associations
250
+ def reader
251
+ result = super
252
+
253
+ if Bullet.start?
254
+ if owner.class.name !~ /^HABTM_/
255
+ if is_a? ::ActiveRecord::Associations::ThroughAssociation
256
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
257
+ association = owner.association(reflection.through_reflection.name)
258
+ Array.wrap(association.target).each do |through_record|
259
+ Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
260
+ end
261
+
262
+ if reflection.through_reflection != through_reflection
263
+ Bullet::Detector::NPlusOneQuery.call_association(owner, through_reflection.name)
264
+ end
265
+ end
266
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
267
+
268
+ if Bullet::Detector::NPlusOneQuery.impossible?(owner)
269
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(result) if result
270
+ else
271
+ Bullet::Detector::NPlusOneQuery.add_possible_objects(result) if result
272
+ end
273
+ end
274
+ end
275
+ result
276
+ end
277
+ end
278
+ )
279
+
280
+ ::ActiveRecord::Associations::HasManyAssociation.prepend(
281
+ Module.new do
282
+ def empty?
283
+ if Bullet.start? && !reflection.has_cached_counter?
284
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name, caller_locations)
285
+ end
286
+ super
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
+ caller_locations
311
+ )
312
+ end
313
+ super(column_name)
314
+ end
315
+ end
316
+ )
317
+ end
318
+ end
319
+ end
@@ -0,0 +1,319 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bullet
4
+ module SaveWithBulletSupport
5
+ def _create_record(*)
6
+ super do
7
+ Bullet::Detector::NPlusOneQuery.update_inversed_object(self)
8
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(self)
9
+ yield(self) if block_given?
10
+ end
11
+ end
12
+ end
13
+
14
+ module ActiveRecord
15
+ def self.enable
16
+ require 'active_record'
17
+ ::ActiveRecord::Base.extend(
18
+ Module.new do
19
+ def find_by_sql(sql, binds = [], preparable: nil, &block)
20
+ result = super
21
+ if Bullet.start?
22
+ if result.is_a? Array
23
+ if result.size > 1
24
+ Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
25
+ Bullet::Detector::CounterCache.add_possible_objects(result)
26
+ elsif result.size == 1
27
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(result.first)
28
+ Bullet::Detector::CounterCache.add_impossible_object(result.first)
29
+ end
30
+ elsif result.is_a? ::ActiveRecord::Base
31
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(result)
32
+ Bullet::Detector::CounterCache.add_impossible_object(result)
33
+ end
34
+ end
35
+ result
36
+ end
37
+ end
38
+ )
39
+
40
+ ::ActiveRecord::Base.prepend(SaveWithBulletSupport)
41
+
42
+ ::ActiveRecord::Relation.prepend(
43
+ Module.new do
44
+ # if select a collection of objects, then these objects have possible to cause N+1 query.
45
+ # if select only one object, then the only one object has impossible to cause N+1 query.
46
+ def records
47
+ result = super
48
+ if Bullet.start?
49
+ if result.first.class.name !~ /^HABTM_/
50
+ if result.size > 1
51
+ Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
52
+ Bullet::Detector::CounterCache.add_possible_objects(result)
53
+ elsif result.size == 1
54
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(result.first)
55
+ Bullet::Detector::CounterCache.add_impossible_object(result.first)
56
+ end
57
+ end
58
+ end
59
+ result
60
+ end
61
+ end
62
+ )
63
+
64
+ ::ActiveRecord::Associations::Preloader::Batch.prepend(
65
+ Module.new do
66
+ def call
67
+ if Bullet.start?
68
+ @preloaders.each do |preloader|
69
+ preloader.records.each { |record|
70
+ Bullet::Detector::Association.add_object_associations(record, preloader.associations)
71
+ }
72
+ Bullet::Detector::UnusedEagerLoading.add_eager_loadings(preloader.records, preloader.associations)
73
+ end
74
+ end
75
+ super
76
+ end
77
+ end
78
+ )
79
+
80
+ ::ActiveRecord::Associations::Preloader::Branch.prepend(
81
+ Module.new do
82
+ def preloaders_for_reflection(reflection, reflection_records)
83
+ if Bullet.start?
84
+ reflection_records.compact!
85
+ if reflection_records.first.class.name !~ /^HABTM_/
86
+ reflection_records.each { |record|
87
+ Bullet::Detector::Association.add_object_associations(record, reflection.name)
88
+ }
89
+ Bullet::Detector::UnusedEagerLoading.add_eager_loadings(reflection_records, reflection.name)
90
+ end
91
+ end
92
+ super
93
+ end
94
+ end
95
+ )
96
+
97
+ ::ActiveRecord::Associations::Preloader::ThroughAssociation.prepend(
98
+ Module.new do
99
+ def source_preloaders
100
+ if Bullet.start? && !defined?(@source_preloaders)
101
+ preloaders = super
102
+ preloaders.each do |preloader|
103
+ reflection_name = preloader.send(:reflection).name
104
+ preloader.send(:owners).each do |owner|
105
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection_name)
106
+ end
107
+ end
108
+ else
109
+ super
110
+ end
111
+ end
112
+ end
113
+ )
114
+
115
+ ::ActiveRecord::Associations::JoinDependency.prepend(
116
+ Module.new do
117
+ def instantiate(result_set, strict_loading_value, &block)
118
+ @bullet_eager_loadings = {}
119
+ records = super
120
+
121
+ if Bullet.start?
122
+ @bullet_eager_loadings.each do |_klazz, eager_loadings_hash|
123
+ objects = eager_loadings_hash.keys
124
+ Bullet::Detector::UnusedEagerLoading.add_eager_loadings(
125
+ objects,
126
+ eager_loadings_hash[objects.first].to_a
127
+ )
128
+ end
129
+ end
130
+ records
131
+ end
132
+
133
+ def construct(ar_parent, parent, row, seen, model_cache, strict_loading_value)
134
+ if Bullet.start?
135
+ unless ar_parent.nil?
136
+ parent.children.each do |node|
137
+ key = aliases.column_alias(node, node.primary_key)
138
+ id = row[key]
139
+ next unless id.nil?
140
+
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
152
+ end
153
+ end
154
+ end
155
+
156
+ super
157
+ end
158
+
159
+ # call join associations
160
+ def construct_model(record, node, row, model_cache, id, strict_loading_value)
161
+ result = super
162
+
163
+ if Bullet.start?
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
175
+ end
176
+
177
+ result
178
+ end
179
+ end
180
+ )
181
+
182
+ ::ActiveRecord::Associations::Association.prepend(
183
+ Module.new do
184
+ def inversed_from(record)
185
+ if Bullet.start?
186
+ Bullet::Detector::NPlusOneQuery.add_inversed_object(owner, reflection.name)
187
+ end
188
+ super
189
+ end
190
+
191
+ def inversed_from_queries(record)
192
+ if Bullet.start? && inversable?(record)
193
+ Bullet::Detector::NPlusOneQuery.add_inversed_object(owner, reflection.name)
194
+ end
195
+ super
196
+ end
197
+ end
198
+ )
199
+
200
+ ::ActiveRecord::Associations::CollectionAssociation.prepend(
201
+ Module.new do
202
+ def load_target
203
+ records = super
204
+
205
+ if Bullet.start?
206
+ if is_a? ::ActiveRecord::Associations::ThroughAssociation
207
+ association = owner.association(reflection.through_reflection.name)
208
+ if association.loaded?
209
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
210
+ Array.wrap(association.target).each do |through_record|
211
+ Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
212
+ end
213
+
214
+ if reflection.through_reflection != through_reflection
215
+ Bullet::Detector::NPlusOneQuery.call_association(owner, through_reflection.name)
216
+ end
217
+ end
218
+ end
219
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
220
+ if records.first.class.name !~ /^HABTM_/
221
+ if records.size > 1
222
+ Bullet::Detector::NPlusOneQuery.add_possible_objects(records)
223
+ Bullet::Detector::CounterCache.add_possible_objects(records)
224
+ elsif records.size == 1
225
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(records.first)
226
+ Bullet::Detector::CounterCache.add_impossible_object(records.first)
227
+ end
228
+ end
229
+ end
230
+ records
231
+ end
232
+
233
+ def empty?
234
+ if Bullet.start? && !reflection.has_cached_counter?
235
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name, caller_locations)
236
+ end
237
+ super
238
+ end
239
+
240
+ def include?(object)
241
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name, caller_locations) if Bullet.start?
242
+ super
243
+ end
244
+ end
245
+ )
246
+
247
+ ::ActiveRecord::Associations::SingularAssociation.prepend(
248
+ Module.new do
249
+ # call has_one and belongs_to associations
250
+ def reader
251
+ result = super
252
+
253
+ if Bullet.start?
254
+ if owner.class.name !~ /^HABTM_/
255
+ if is_a? ::ActiveRecord::Associations::ThroughAssociation
256
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
257
+ association = owner.association(reflection.through_reflection.name)
258
+ Array.wrap(association.target).each do |through_record|
259
+ Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
260
+ end
261
+
262
+ if reflection.through_reflection != through_reflection
263
+ Bullet::Detector::NPlusOneQuery.call_association(owner, through_reflection.name)
264
+ end
265
+ end
266
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
267
+
268
+ if Bullet::Detector::NPlusOneQuery.impossible?(owner)
269
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(result) if result
270
+ else
271
+ Bullet::Detector::NPlusOneQuery.add_possible_objects(result) if result
272
+ end
273
+ end
274
+ end
275
+ result
276
+ end
277
+ end
278
+ )
279
+
280
+ ::ActiveRecord::Associations::HasManyAssociation.prepend(
281
+ Module.new do
282
+ def empty?
283
+ if Bullet.start? && !reflection.has_cached_counter?
284
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name, caller_locations)
285
+ end
286
+ super
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
+ caller_locations
311
+ )
312
+ end
313
+ super(column_name)
314
+ end
315
+ end
316
+ )
317
+ end
318
+ end
319
+ end