bullet 6.0.0 → 6.1.2

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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +20 -1
  3. data/CHANGELOG.md +26 -1
  4. data/Gemfile.rails-6.0 +1 -1
  5. data/Gemfile.rails-6.1 +15 -0
  6. data/README.md +30 -9
  7. data/lib/bullet.rb +26 -16
  8. data/lib/bullet/active_job.rb +13 -0
  9. data/lib/bullet/active_record4.rb +9 -24
  10. data/lib/bullet/active_record41.rb +7 -19
  11. data/lib/bullet/active_record42.rb +8 -16
  12. data/lib/bullet/active_record5.rb +188 -170
  13. data/lib/bullet/active_record52.rb +176 -161
  14. data/lib/bullet/active_record60.rb +193 -171
  15. data/lib/bullet/active_record61.rb +267 -0
  16. data/lib/bullet/bullet_xhr.js +32 -27
  17. data/lib/bullet/dependency.rb +42 -34
  18. data/lib/bullet/detector/association.rb +24 -18
  19. data/lib/bullet/detector/base.rb +1 -2
  20. data/lib/bullet/detector/counter_cache.rb +10 -6
  21. data/lib/bullet/detector/n_plus_one_query.rb +18 -8
  22. data/lib/bullet/detector/unused_eager_loading.rb +5 -2
  23. data/lib/bullet/mongoid4x.rb +2 -6
  24. data/lib/bullet/mongoid5x.rb +2 -6
  25. data/lib/bullet/mongoid6x.rb +2 -6
  26. data/lib/bullet/mongoid7x.rb +2 -6
  27. data/lib/bullet/notification/base.rb +14 -18
  28. data/lib/bullet/notification/n_plus_one_query.rb +2 -4
  29. data/lib/bullet/notification/unused_eager_loading.rb +2 -4
  30. data/lib/bullet/rack.rb +21 -13
  31. data/lib/bullet/stack_trace_filter.rb +5 -10
  32. data/lib/bullet/version.rb +1 -1
  33. data/lib/generators/bullet/install_generator.rb +23 -23
  34. data/perf/benchmark.rb +8 -14
  35. data/spec/bullet/detector/counter_cache_spec.rb +6 -6
  36. data/spec/bullet/detector/n_plus_one_query_spec.rb +7 -3
  37. data/spec/bullet/detector/unused_eager_loading_spec.rb +19 -6
  38. data/spec/bullet/notification/base_spec.rb +1 -3
  39. data/spec/bullet/notification/n_plus_one_query_spec.rb +16 -3
  40. data/spec/bullet/notification/unused_eager_loading_spec.rb +5 -1
  41. data/spec/bullet/rack_spec.rb +76 -5
  42. data/spec/bullet/registry/association_spec.rb +2 -2
  43. data/spec/bullet/registry/base_spec.rb +1 -1
  44. data/spec/bullet_spec.rb +10 -29
  45. data/spec/integration/active_record/association_spec.rb +41 -122
  46. data/spec/integration/counter_cache_spec.rb +10 -30
  47. data/spec/integration/mongoid/association_spec.rb +18 -32
  48. data/spec/models/folder.rb +1 -2
  49. data/spec/models/group.rb +1 -2
  50. data/spec/models/page.rb +1 -2
  51. data/spec/models/writer.rb +1 -2
  52. data/spec/spec_helper.rb +6 -10
  53. data/spec/support/bullet_ext.rb +8 -9
  54. data/spec/support/mongo_seed.rb +2 -16
  55. metadata +9 -6
@@ -13,213 +13,228 @@ module Bullet
13
13
  module ActiveRecord
14
14
  def self.enable
15
15
  require 'active_record'
16
- ::ActiveRecord::Base.extend(Module.new do
17
- def find_by_sql(sql, binds = [], preparable: nil, &block)
18
- result = super
19
- if Bullet.start?
20
- if result.is_a? Array
21
- if result.size > 1
22
- Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
23
- Bullet::Detector::CounterCache.add_possible_objects(result)
24
- elsif result.size == 1
25
- Bullet::Detector::NPlusOneQuery.add_impossible_object(result.first)
26
- Bullet::Detector::CounterCache.add_impossible_object(result.first)
16
+ ::ActiveRecord::Base.extend(
17
+ Module.new do
18
+ def find_by_sql(sql, binds = [], preparable: nil, &block)
19
+ result = super
20
+ if Bullet.start?
21
+ if result.is_a? Array
22
+ if result.size > 1
23
+ Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
24
+ Bullet::Detector::CounterCache.add_possible_objects(result)
25
+ elsif result.size == 1
26
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(result.first)
27
+ Bullet::Detector::CounterCache.add_impossible_object(result.first)
28
+ end
29
+ elsif result.is_a? ::ActiveRecord::Base
30
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(result)
31
+ Bullet::Detector::CounterCache.add_impossible_object(result)
27
32
  end
28
- elsif result.is_a? ::ActiveRecord::Base
29
- Bullet::Detector::NPlusOneQuery.add_impossible_object(result)
30
- Bullet::Detector::CounterCache.add_impossible_object(result)
31
33
  end
34
+ result
32
35
  end
33
- result
34
36
  end
35
- end)
37
+ )
36
38
 
37
39
  ::ActiveRecord::Base.prepend(SaveWithBulletSupport)
38
40
 
39
- ::ActiveRecord::Relation.prepend(Module.new do
40
- # if select a collection of objects, then these objects have possible to cause N+1 query.
41
- # if select only one object, then the only one object has impossible to cause N+1 query.
42
- def records
43
- result = super
44
- if Bullet.start?
45
- if result.first.class.name !~ /^HABTM_/
46
- if result.size > 1
47
- Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
48
- Bullet::Detector::CounterCache.add_possible_objects(result)
49
- elsif result.size == 1
50
- Bullet::Detector::NPlusOneQuery.add_impossible_object(result.first)
51
- Bullet::Detector::CounterCache.add_impossible_object(result.first)
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
52
56
  end
53
57
  end
58
+ result
54
59
  end
55
- result
56
60
  end
57
- end)
58
-
59
- ::ActiveRecord::Associations::Preloader.prepend(Module.new do
60
- def preloaders_for_one(association, records, scope)
61
- if Bullet.start?
62
- records.compact!
63
- if records.first.class.name !~ /^HABTM_/
64
- records.each do |record|
65
- Bullet::Detector::Association.add_object_associations(record, association)
61
+ )
62
+
63
+ ::ActiveRecord::Associations::Preloader.prepend(
64
+ Module.new do
65
+ def preloaders_for_one(association, records, scope)
66
+ if Bullet.start?
67
+ records.compact!
68
+ if records.first.class.name !~ /^HABTM_/
69
+ records.each { |record| Bullet::Detector::Association.add_object_associations(record, association) }
70
+ Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, association)
66
71
  end
67
- Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, association)
68
72
  end
73
+ super
69
74
  end
70
- super
71
75
  end
72
- end)
73
-
74
- ::ActiveRecord::FinderMethods.prepend(Module.new do
75
- # add includes in scope
76
- def find_with_associations
77
- return super { |r| yield r } if block_given?
78
-
79
- records = super
80
- if Bullet.start?
81
- associations = (eager_load_values + includes_values).uniq
82
- records.each do |record|
83
- Bullet::Detector::Association.add_object_associations(record, associations)
76
+ )
77
+
78
+ ::ActiveRecord::FinderMethods.prepend(
79
+ Module.new do
80
+ # add includes in scope
81
+ def find_with_associations
82
+ return super { |r| yield r } if block_given?
83
+
84
+ records = super
85
+ if Bullet.start?
86
+ associations = (eager_load_values + includes_values).uniq
87
+ records.each { |record| Bullet::Detector::Association.add_object_associations(record, associations) }
88
+ Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, associations)
84
89
  end
85
- Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, associations)
90
+ records
86
91
  end
87
- records
88
92
  end
89
- end)
90
-
91
- ::ActiveRecord::Associations::JoinDependency.prepend(Module.new do
92
- def instantiate(result_set, &block)
93
- @bullet_eager_loadings = {}
94
- records = super
95
-
96
- if Bullet.start?
97
- @bullet_eager_loadings.each do |_klazz, eager_loadings_hash|
98
- objects = eager_loadings_hash.keys
99
- Bullet::Detector::UnusedEagerLoading.add_eager_loadings(objects, eager_loadings_hash[objects.first].to_a)
93
+ )
94
+
95
+ ::ActiveRecord::Associations::JoinDependency.prepend(
96
+ Module.new do
97
+ def instantiate(result_set, &block)
98
+ @bullet_eager_loadings = {}
99
+ records = super
100
+
101
+ if Bullet.start?
102
+ @bullet_eager_loadings.each do |_klazz, eager_loadings_hash|
103
+ objects = eager_loadings_hash.keys
104
+ Bullet::Detector::UnusedEagerLoading.add_eager_loadings(
105
+ objects,
106
+ eager_loadings_hash[objects.first].to_a
107
+ )
108
+ end
100
109
  end
110
+ records
101
111
  end
102
- records
103
- end
104
112
 
105
- def construct(ar_parent, parent, row, rs, seen, model_cache, aliases)
106
- if Bullet.start?
107
- unless ar_parent.nil?
108
- parent.children.each do |node|
109
- key = aliases.column_alias(node, node.primary_key)
110
- id = row[key]
111
- next unless id.nil?
112
-
113
- associations = node.reflection.name
114
- Bullet::Detector::Association.add_object_associations(ar_parent, associations)
115
- Bullet::Detector::NPlusOneQuery.call_association(ar_parent, associations)
116
- @bullet_eager_loadings[ar_parent.class] ||= {}
117
- @bullet_eager_loadings[ar_parent.class][ar_parent] ||= Set.new
118
- @bullet_eager_loadings[ar_parent.class][ar_parent] << associations
113
+ def construct(ar_parent, parent, row, rs, seen, model_cache, aliases)
114
+ if Bullet.start?
115
+ unless ar_parent.nil?
116
+ parent.children.each do |node|
117
+ key = aliases.column_alias(node, node.primary_key)
118
+ id = row[key]
119
+ next unless id.nil?
120
+
121
+ associations = node.reflection.name
122
+ Bullet::Detector::Association.add_object_associations(ar_parent, associations)
123
+ Bullet::Detector::NPlusOneQuery.call_association(ar_parent, associations)
124
+ @bullet_eager_loadings[ar_parent.class] ||= {}
125
+ @bullet_eager_loadings[ar_parent.class][ar_parent] ||= Set.new
126
+ @bullet_eager_loadings[ar_parent.class][ar_parent] << associations
127
+ end
119
128
  end
120
129
  end
130
+
131
+ super
121
132
  end
122
133
 
123
- super
124
- end
134
+ # call join associations
135
+ def construct_model(record, node, row, model_cache, id, aliases)
136
+ result = super
125
137
 
126
- # call join associations
127
- def construct_model(record, node, row, model_cache, id, aliases)
128
- result = super
129
-
130
- if Bullet.start?
131
- associations = node.reflection.name
132
- Bullet::Detector::Association.add_object_associations(record, associations)
133
- Bullet::Detector::NPlusOneQuery.call_association(record, associations)
134
- @bullet_eager_loadings[record.class] ||= {}
135
- @bullet_eager_loadings[record.class][record] ||= Set.new
136
- @bullet_eager_loadings[record.class][record] << associations
137
- end
138
+ if Bullet.start?
139
+ associations = node.reflection.name
140
+ Bullet::Detector::Association.add_object_associations(record, associations)
141
+ Bullet::Detector::NPlusOneQuery.call_association(record, associations)
142
+ @bullet_eager_loadings[record.class] ||= {}
143
+ @bullet_eager_loadings[record.class][record] ||= Set.new
144
+ @bullet_eager_loadings[record.class][record] << associations
145
+ end
138
146
 
139
- result
147
+ result
148
+ end
140
149
  end
141
- end)
142
-
143
- ::ActiveRecord::Associations::CollectionAssociation.prepend(Module.new do
144
- def load_target
145
- records = super
146
-
147
- if Bullet.start?
148
- if is_a? ::ActiveRecord::Associations::ThroughAssociation
149
- Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
150
- association = owner.association reflection.through_reflection.name
151
- Array(association.target).each do |through_record|
152
- Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
150
+ )
151
+
152
+ ::ActiveRecord::Associations::CollectionAssociation.prepend(
153
+ Module.new do
154
+ def load_target
155
+ records = super
156
+
157
+ if Bullet.start?
158
+ if is_a? ::ActiveRecord::Associations::ThroughAssociation
159
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
160
+ association = owner.association reflection.through_reflection.name
161
+ Array(association.target).each do |through_record|
162
+ Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
163
+ end
164
+
165
+ if reflection.through_reflection != through_reflection
166
+ Bullet::Detector::NPlusOneQuery.call_association(owner, through_reflection.name)
167
+ end
153
168
  end
154
-
155
- if reflection.through_reflection != through_reflection
156
- Bullet::Detector::NPlusOneQuery.call_association(owner, through_reflection.name)
157
- end
158
- end
159
- Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name) unless @inversed
160
- if records.first.class.name !~ /^HABTM_/
161
- if records.size > 1
162
- Bullet::Detector::NPlusOneQuery.add_possible_objects(records)
163
- Bullet::Detector::CounterCache.add_possible_objects(records)
164
- elsif records.size == 1
165
- Bullet::Detector::NPlusOneQuery.add_impossible_object(records.first)
166
- Bullet::Detector::CounterCache.add_impossible_object(records.first)
169
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name) unless @inversed
170
+ if records.first.class.name !~ /^HABTM_/
171
+ if records.size > 1
172
+ Bullet::Detector::NPlusOneQuery.add_possible_objects(records)
173
+ Bullet::Detector::CounterCache.add_possible_objects(records)
174
+ elsif records.size == 1
175
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(records.first)
176
+ Bullet::Detector::CounterCache.add_impossible_object(records.first)
177
+ end
167
178
  end
168
179
  end
180
+ records
169
181
  end
170
- records
171
- end
172
182
 
173
- def empty?
174
- if Bullet.start? && !reflection.has_cached_counter?
175
- Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
183
+ def empty?
184
+ if Bullet.start? && !reflection.has_cached_counter?
185
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
186
+ end
187
+ super
176
188
  end
177
- super
178
- end
179
189
 
180
- def include?(object)
181
- if Bullet.start?
182
- Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
190
+ def include?(object)
191
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name) if Bullet.start?
192
+ super
183
193
  end
184
- super
185
194
  end
186
- end)
187
-
188
- ::ActiveRecord::Associations::SingularAssociation.prepend(Module.new do
189
- # call has_one and belongs_to associations
190
- def target
191
- result = super()
192
- if Bullet.start?
193
- if owner.class.name !~ /^HABTM_/ && !@inversed
194
- Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
195
- if Bullet::Detector::NPlusOneQuery.impossible?(owner)
196
- Bullet::Detector::NPlusOneQuery.add_impossible_object(result) if result
197
- else
198
- Bullet::Detector::NPlusOneQuery.add_possible_objects(result) if result
195
+ )
196
+
197
+ ::ActiveRecord::Associations::SingularAssociation.prepend(
198
+ Module.new do
199
+ # call has_one and belongs_to associations
200
+ def target
201
+ result = super()
202
+
203
+ if Bullet.start?
204
+ if owner.class.name !~ /^HABTM_/ && !@inversed
205
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
206
+
207
+ if Bullet::Detector::NPlusOneQuery.impossible?(owner)
208
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(result) if result
209
+ else
210
+ Bullet::Detector::NPlusOneQuery.add_possible_objects(result) if result
211
+ end
199
212
  end
200
213
  end
214
+ result
201
215
  end
202
- result
203
216
  end
204
- end)
217
+ )
205
218
 
206
- ::ActiveRecord::Associations::HasManyAssociation.prepend(Module.new do
207
- def empty?
208
- result = super
209
- if Bullet.start? && !reflection.has_cached_counter?
210
- Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
219
+ ::ActiveRecord::Associations::HasManyAssociation.prepend(
220
+ Module.new do
221
+ def empty?
222
+ result = super
223
+ if Bullet.start? && !reflection.has_cached_counter?
224
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
225
+ end
226
+ result
211
227
  end
212
- result
213
- end
214
228
 
215
- def count_records
216
- result = reflection.has_cached_counter?
217
- if Bullet.start? && !result && !is_a?(::ActiveRecord::Associations::ThroughAssociation)
218
- Bullet::Detector::CounterCache.add_counter_cache(owner, reflection.name)
229
+ def count_records
230
+ result = reflection.has_cached_counter?
231
+ if Bullet.start? && !result && !is_a?(::ActiveRecord::Associations::ThroughAssociation)
232
+ Bullet::Detector::CounterCache.add_counter_cache(owner, reflection.name)
233
+ end
234
+ super
219
235
  end
220
- super
221
236
  end
222
- end)
237
+ )
223
238
  end
224
239
  end
225
240
  end
@@ -13,233 +13,255 @@ module Bullet
13
13
  module ActiveRecord
14
14
  def self.enable
15
15
  require 'active_record'
16
- ::ActiveRecord::Base.extend(Module.new do
17
- def find_by_sql(sql, binds = [], preparable: nil, &block)
18
- result = super
19
- if Bullet.start?
20
- if result.is_a? Array
21
- if result.size > 1
22
- Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
23
- Bullet::Detector::CounterCache.add_possible_objects(result)
24
- elsif result.size == 1
25
- Bullet::Detector::NPlusOneQuery.add_impossible_object(result.first)
26
- Bullet::Detector::CounterCache.add_impossible_object(result.first)
16
+ ::ActiveRecord::Base.extend(
17
+ Module.new do
18
+ def find_by_sql(sql, binds = [], preparable: nil, &block)
19
+ result = super
20
+ if Bullet.start?
21
+ if result.is_a? Array
22
+ if result.size > 1
23
+ Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
24
+ Bullet::Detector::CounterCache.add_possible_objects(result)
25
+ elsif result.size == 1
26
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(result.first)
27
+ Bullet::Detector::CounterCache.add_impossible_object(result.first)
28
+ end
29
+ elsif result.is_a? ::ActiveRecord::Base
30
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(result)
31
+ Bullet::Detector::CounterCache.add_impossible_object(result)
27
32
  end
28
- elsif result.is_a? ::ActiveRecord::Base
29
- Bullet::Detector::NPlusOneQuery.add_impossible_object(result)
30
- Bullet::Detector::CounterCache.add_impossible_object(result)
31
33
  end
34
+ result
32
35
  end
33
- result
34
36
  end
35
- end)
37
+ )
36
38
 
37
39
  ::ActiveRecord::Base.prepend(SaveWithBulletSupport)
38
40
 
39
- ::ActiveRecord::Relation.prepend(Module.new do
40
- # if select a collection of objects, then these objects have possible to cause N+1 query.
41
- # if select only one object, then the only one object has impossible to cause N+1 query.
42
- def records
43
- result = super
44
- if Bullet.start?
45
- if result.first.class.name !~ /^HABTM_/
46
- if result.size > 1
47
- Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
48
- Bullet::Detector::CounterCache.add_possible_objects(result)
49
- elsif result.size == 1
50
- Bullet::Detector::NPlusOneQuery.add_impossible_object(result.first)
51
- Bullet::Detector::CounterCache.add_impossible_object(result.first)
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
52
56
  end
53
57
  end
58
+ result
54
59
  end
55
- result
56
60
  end
57
- end)
58
-
59
- ::ActiveRecord::Associations::Preloader.prepend(Module.new do
60
- def preloaders_for_one(association, records, scope, polymorphic_parent)
61
- if Bullet.start?
62
- records.compact!
63
- if records.first.class.name !~ /^HABTM_/
64
- records.each do |record|
65
- Bullet::Detector::Association.add_object_associations(record, association)
61
+ )
62
+
63
+ ::ActiveRecord::Associations::Preloader.prepend(
64
+ Module.new do
65
+ def preloaders_for_one(association, records, scope, polymorphic_parent)
66
+ if Bullet.start?
67
+ records.compact!
68
+ if records.first.class.name !~ /^HABTM_/
69
+ records.each { |record| Bullet::Detector::Association.add_object_associations(record, association) }
70
+ Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, association)
66
71
  end
67
- Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, association)
68
72
  end
73
+ super
69
74
  end
70
- super
71
- end
72
75
 
73
- def preloaders_for_reflection(reflection, records, scope)
74
- if Bullet.start?
75
- records.compact!
76
- if records.first.class.name !~ /^HABTM_/
77
- records.each do |record|
78
- Bullet::Detector::Association.add_object_associations(record, reflection.name)
76
+ def preloaders_for_reflection(reflection, records, scope)
77
+ if Bullet.start?
78
+ records.compact!
79
+ if records.first.class.name !~ /^HABTM_/
80
+ records.each { |record| Bullet::Detector::Association.add_object_associations(record, reflection.name) }
81
+ Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, reflection.name)
79
82
  end
80
- Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, reflection.name)
81
83
  end
84
+ super
82
85
  end
83
- super
84
86
  end
85
- end)
86
-
87
- ::ActiveRecord::FinderMethods.prepend(Module.new do
88
- # add includes in scope
89
- def find_with_associations
90
- return super { |r| yield r } if block_given?
87
+ )
91
88
 
92
- records = super
93
- if Bullet.start?
94
- associations = (eager_load_values + includes_values).uniq
95
- records.each do |record|
96
- Bullet::Detector::Association.add_object_associations(record, associations)
89
+ ::ActiveRecord::Associations::Preloader::ThroughAssociation.prepend(
90
+ Module.new do
91
+ def preloaded_records
92
+ if Bullet.start? && !defined?(@preloaded_records)
93
+ source_preloaders.each do |source_preloader|
94
+ reflection_name = source_preloader.send(:reflection).name
95
+ source_preloader.send(:owners).each do |owner|
96
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection_name)
97
+ end
98
+ end
97
99
  end
98
- Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, associations)
100
+ super
99
101
  end
100
- records
101
102
  end
102
- end)
103
+ )
103
104
 
104
- ::ActiveRecord::Associations::JoinDependency.prepend(Module.new do
105
- def instantiate(result_set, &block)
106
- @bullet_eager_loadings = {}
107
- records = super
105
+ ::ActiveRecord::FinderMethods.prepend(
106
+ Module.new do
107
+ # add includes in scope
108
+ def find_with_associations
109
+ return super { |r| yield r } if block_given?
108
110
 
109
- if Bullet.start?
110
- @bullet_eager_loadings.each do |_klazz, eager_loadings_hash|
111
- objects = eager_loadings_hash.keys
112
- Bullet::Detector::UnusedEagerLoading.add_eager_loadings(objects, eager_loadings_hash[objects.first].to_a)
111
+ records = super
112
+ if Bullet.start?
113
+ associations = (eager_load_values + includes_values).uniq
114
+ records.each { |record| Bullet::Detector::Association.add_object_associations(record, associations) }
115
+ Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, associations)
113
116
  end
117
+ records
114
118
  end
115
- records
116
119
  end
120
+ )
117
121
 
118
- def construct(ar_parent, parent, row, seen, model_cache)
119
- if Bullet.start?
120
- unless ar_parent.nil?
121
- parent.children.each do |node|
122
- key = aliases.column_alias(node, node.primary_key)
123
- id = row[key]
124
- next unless id.nil?
125
-
126
- associations = node.reflection.name
127
- Bullet::Detector::Association.add_object_associations(ar_parent, associations)
128
- Bullet::Detector::NPlusOneQuery.call_association(ar_parent, associations)
129
- @bullet_eager_loadings[ar_parent.class] ||= {}
130
- @bullet_eager_loadings[ar_parent.class][ar_parent] ||= Set.new
131
- @bullet_eager_loadings[ar_parent.class][ar_parent] << associations
122
+ ::ActiveRecord::Associations::JoinDependency.prepend(
123
+ Module.new do
124
+ def instantiate(result_set, &block)
125
+ @bullet_eager_loadings = {}
126
+ records = super
127
+
128
+ if Bullet.start?
129
+ @bullet_eager_loadings.each do |_klazz, eager_loadings_hash|
130
+ objects = eager_loadings_hash.keys
131
+ Bullet::Detector::UnusedEagerLoading.add_eager_loadings(
132
+ objects,
133
+ eager_loadings_hash[objects.first].to_a
134
+ )
132
135
  end
133
136
  end
137
+ records
134
138
  end
135
139
 
136
- super
137
- end
140
+ def construct(ar_parent, parent, row, seen, model_cache)
141
+ if Bullet.start?
142
+ unless ar_parent.nil?
143
+ parent.children.each do |node|
144
+ key = aliases.column_alias(node, node.primary_key)
145
+ id = row[key]
146
+ next unless id.nil?
138
147
 
139
- # call join associations
140
- def construct_model(record, node, row, model_cache, id)
141
- result = super
142
-
143
- if Bullet.start?
144
- associations = node.reflection.name
145
- Bullet::Detector::Association.add_object_associations(record, associations)
146
- Bullet::Detector::NPlusOneQuery.call_association(record, associations)
147
- @bullet_eager_loadings[record.class] ||= {}
148
- @bullet_eager_loadings[record.class][record] ||= Set.new
149
- @bullet_eager_loadings[record.class][record] << associations
148
+ associations = node.reflection.name
149
+ Bullet::Detector::Association.add_object_associations(ar_parent, associations)
150
+ Bullet::Detector::NPlusOneQuery.call_association(ar_parent, associations)
151
+ @bullet_eager_loadings[ar_parent.class] ||= {}
152
+ @bullet_eager_loadings[ar_parent.class][ar_parent] ||= Set.new
153
+ @bullet_eager_loadings[ar_parent.class][ar_parent] << associations
154
+ end
155
+ end
156
+ end
157
+
158
+ super
150
159
  end
151
160
 
152
- result
161
+ # call join associations
162
+ def construct_model(record, node, row, model_cache, id)
163
+ result = super
164
+
165
+ if Bullet.start?
166
+ associations = node.reflection.name
167
+ Bullet::Detector::Association.add_object_associations(record, associations)
168
+ Bullet::Detector::NPlusOneQuery.call_association(record, associations)
169
+ @bullet_eager_loadings[record.class] ||= {}
170
+ @bullet_eager_loadings[record.class][record] ||= Set.new
171
+ @bullet_eager_loadings[record.class][record] << associations
172
+ end
173
+
174
+ result
175
+ end
153
176
  end
154
- end)
155
-
156
- ::ActiveRecord::Associations::CollectionAssociation.prepend(Module.new do
157
- def load_target
158
- records = super
159
-
160
- if Bullet.start?
161
- if is_a? ::ActiveRecord::Associations::ThroughAssociation
162
- Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
163
- association = owner.association reflection.through_reflection.name
164
- Array(association.target).each do |through_record|
165
- Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
166
- end
177
+ )
178
+
179
+ ::ActiveRecord::Associations::CollectionAssociation.prepend(
180
+ Module.new do
181
+ def load_target
182
+ records = super
167
183
 
168
- if reflection.through_reflection != through_reflection
169
- Bullet::Detector::NPlusOneQuery.call_association(owner, through_reflection.name)
184
+ if Bullet.start?
185
+ if is_a? ::ActiveRecord::Associations::ThroughAssociation
186
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
187
+ association = owner.association(reflection.through_reflection.name)
188
+ Array(association.target).each do |through_record|
189
+ Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
190
+ end
191
+
192
+ if reflection.through_reflection != through_reflection
193
+ Bullet::Detector::NPlusOneQuery.call_association(owner, through_reflection.name)
194
+ end
170
195
  end
171
- end
172
- Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name) unless @inversed
173
- if records.first.class.name !~ /^HABTM_/
174
- if records.size > 1
175
- Bullet::Detector::NPlusOneQuery.add_possible_objects(records)
176
- Bullet::Detector::CounterCache.add_possible_objects(records)
177
- elsif records.size == 1
178
- Bullet::Detector::NPlusOneQuery.add_impossible_object(records.first)
179
- Bullet::Detector::CounterCache.add_impossible_object(records.first)
196
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name) unless @inversed
197
+ if records.first.class.name !~ /^HABTM_/
198
+ if records.size > 1
199
+ Bullet::Detector::NPlusOneQuery.add_possible_objects(records)
200
+ Bullet::Detector::CounterCache.add_possible_objects(records)
201
+ elsif records.size == 1
202
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(records.first)
203
+ Bullet::Detector::CounterCache.add_impossible_object(records.first)
204
+ end
180
205
  end
181
206
  end
207
+ records
182
208
  end
183
- records
184
- end
185
209
 
186
- def empty?
187
- if Bullet.start? && !reflection.has_cached_counter?
188
- Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
210
+ def empty?
211
+ if Bullet.start? && !reflection.has_cached_counter?
212
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
213
+ end
214
+ super
189
215
  end
190
- super
191
- end
192
216
 
193
- def include?(object)
194
- if Bullet.start?
195
- Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
217
+ def include?(object)
218
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name) if Bullet.start?
219
+ super
196
220
  end
197
- super
198
221
  end
199
- end)
200
-
201
- ::ActiveRecord::Associations::SingularAssociation.prepend(Module.new do
202
- # call has_one and belongs_to associations
203
- def target
204
- result = super()
205
- if Bullet.start?
206
- if owner.class.name !~ /^HABTM_/ && !@inversed
207
- Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
208
- if Bullet::Detector::NPlusOneQuery.impossible?(owner)
209
- Bullet::Detector::NPlusOneQuery.add_impossible_object(result) if result
210
- else
211
- Bullet::Detector::NPlusOneQuery.add_possible_objects(result) if result
222
+ )
223
+
224
+ ::ActiveRecord::Associations::SingularAssociation.prepend(
225
+ Module.new do
226
+ # call has_one and belongs_to associations
227
+ def target
228
+ result = super()
229
+
230
+ if Bullet.start?
231
+ if owner.class.name !~ /^HABTM_/ && !@inversed
232
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
233
+
234
+ if Bullet::Detector::NPlusOneQuery.impossible?(owner)
235
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(result) if result
236
+ else
237
+ Bullet::Detector::NPlusOneQuery.add_possible_objects(result) if result
238
+ end
212
239
  end
213
240
  end
241
+ result
214
242
  end
215
- result
216
243
  end
217
- end)
244
+ )
218
245
 
219
- ::ActiveRecord::Associations::HasManyAssociation.prepend(Module.new do
220
- def empty?
221
- result = super
222
- if Bullet.start? && !reflection.has_cached_counter?
223
- Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
246
+ ::ActiveRecord::Associations::HasManyAssociation.prepend(
247
+ Module.new do
248
+ def empty?
249
+ result = super
250
+ if Bullet.start? && !reflection.has_cached_counter?
251
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
252
+ end
253
+ result
224
254
  end
225
- result
226
- end
227
255
 
228
- def count_records
229
- result = reflection.has_cached_counter?
230
- if Bullet.start? && !result && !is_a?(::ActiveRecord::Associations::ThroughAssociation)
231
- Bullet::Detector::CounterCache.add_counter_cache(owner, reflection.name)
256
+ def count_records
257
+ result = reflection.has_cached_counter?
258
+ if Bullet.start? && !result && !is_a?(::ActiveRecord::Associations::ThroughAssociation)
259
+ Bullet::Detector::CounterCache.add_counter_cache(owner, reflection.name)
260
+ end
261
+ super
232
262
  end
233
- super
234
- end
235
- end)
236
-
237
- ::ActiveRecord::Associations::BelongsToAssociation.prepend(Module.new do
238
- def writer(record)
239
- Bullet::Detector::Association.add_object_associations(owner, reflection.name) if Bullet.start?
240
- super
241
263
  end
242
- end)
264
+ )
243
265
  end
244
266
  end
245
267
  end