bullet 6.0.0 → 6.1.2

Sign up to get free protection for your applications and to get access to all the features.
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