bullet 5.9.0 → 7.0.4

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