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
@@ -0,0 +1,277 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bullet
4
+ module SaveWithBulletSupport
5
+ def _create_record(*)
6
+ super do
7
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(self)
8
+ yield(self) if block_given?
9
+ end
10
+ end
11
+ end
12
+
13
+ module ActiveRecord
14
+ def self.enable
15
+ require 'active_record'
16
+ ::ActiveRecord::Base.extend(
17
+ Module.new do
18
+ def find_by_sql(sql, binds = [], preparable: nil, &block)
19
+ result = super
20
+ if Bullet.start?
21
+ if result.is_a? Array
22
+ if result.size > 1
23
+ Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
24
+ Bullet::Detector::CounterCache.add_possible_objects(result)
25
+ elsif result.size == 1
26
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(result.first)
27
+ Bullet::Detector::CounterCache.add_impossible_object(result.first)
28
+ end
29
+ elsif result.is_a? ::ActiveRecord::Base
30
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(result)
31
+ Bullet::Detector::CounterCache.add_impossible_object(result)
32
+ end
33
+ end
34
+ result
35
+ end
36
+ end
37
+ )
38
+
39
+ ::ActiveRecord::Base.prepend(SaveWithBulletSupport)
40
+
41
+ ::ActiveRecord::Relation.prepend(
42
+ Module.new do
43
+ # if select a collection of objects, then these objects have possible to cause N+1 query.
44
+ # if select only one object, then the only one object has impossible to cause N+1 query.
45
+ def records
46
+ result = super
47
+ if Bullet.start?
48
+ if result.first.class.name !~ /^HABTM_/
49
+ if result.size > 1
50
+ Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
51
+ Bullet::Detector::CounterCache.add_possible_objects(result)
52
+ elsif result.size == 1
53
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(result.first)
54
+ Bullet::Detector::CounterCache.add_impossible_object(result.first)
55
+ end
56
+ end
57
+ end
58
+ result
59
+ end
60
+ end
61
+ )
62
+
63
+ ::ActiveRecord::Associations::Preloader::Batch.prepend(
64
+ Module.new do
65
+ def call
66
+ if Bullet.start?
67
+ @preloaders.each do |preloader|
68
+ preloader.records.each { |record| Bullet::Detector::Association.add_object_associations(record, preloader.associations) }
69
+ Bullet::Detector::UnusedEagerLoading.add_eager_loadings(preloader.records, preloader.associations)
70
+ end
71
+ end
72
+ super
73
+ end
74
+ end
75
+ )
76
+
77
+ ::ActiveRecord::Associations::Preloader::Branch.prepend(
78
+ Module.new do
79
+ def preloaders_for_reflection(reflection, reflection_records)
80
+ if Bullet.start?
81
+ reflection_records.compact!
82
+ if reflection_records.first.class.name !~ /^HABTM_/
83
+ reflection_records.each { |record| Bullet::Detector::Association.add_object_associations(record, reflection.name) }
84
+ Bullet::Detector::UnusedEagerLoading.add_eager_loadings(reflection_records, reflection.name)
85
+ end
86
+ end
87
+ super
88
+ end
89
+ end
90
+ )
91
+
92
+ ::ActiveRecord::Associations::Preloader::ThroughAssociation.prepend(
93
+ Module.new do
94
+ def preloaded_records
95
+ if Bullet.start? && !defined?(@preloaded_records)
96
+ source_preloaders.each do |source_preloader|
97
+ reflection_name = source_preloader.send(:reflection).name
98
+ source_preloader.send(:owners).each do |owner|
99
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection_name)
100
+ end
101
+ end
102
+ end
103
+ super
104
+ end
105
+ end
106
+ )
107
+
108
+ ::ActiveRecord::Associations::JoinDependency.prepend(
109
+ Module.new do
110
+ def instantiate(result_set, strict_loading_value, &block)
111
+ @bullet_eager_loadings = {}
112
+ records = super
113
+
114
+ if Bullet.start?
115
+ @bullet_eager_loadings.each do |_klazz, eager_loadings_hash|
116
+ objects = eager_loadings_hash.keys
117
+ Bullet::Detector::UnusedEagerLoading.add_eager_loadings(
118
+ objects,
119
+ eager_loadings_hash[objects.first].to_a
120
+ )
121
+ end
122
+ end
123
+ records
124
+ end
125
+
126
+ def construct(ar_parent, parent, row, seen, model_cache, strict_loading_value)
127
+ if Bullet.start?
128
+ unless ar_parent.nil?
129
+ parent.children.each do |node|
130
+ key = aliases.column_alias(node, node.primary_key)
131
+ id = row[key]
132
+ next unless id.nil?
133
+
134
+ associations = node.reflection.name
135
+ Bullet::Detector::Association.add_object_associations(ar_parent, associations)
136
+ Bullet::Detector::NPlusOneQuery.call_association(ar_parent, associations)
137
+ @bullet_eager_loadings[ar_parent.class] ||= {}
138
+ @bullet_eager_loadings[ar_parent.class][ar_parent] ||= Set.new
139
+ @bullet_eager_loadings[ar_parent.class][ar_parent] << associations
140
+ end
141
+ end
142
+ end
143
+
144
+ super
145
+ end
146
+
147
+ # call join associations
148
+ def construct_model(record, node, row, model_cache, id, strict_loading_value)
149
+ result = super
150
+
151
+ if Bullet.start?
152
+ associations = node.reflection.name
153
+ Bullet::Detector::Association.add_object_associations(record, associations)
154
+ Bullet::Detector::NPlusOneQuery.call_association(record, associations)
155
+ @bullet_eager_loadings[record.class] ||= {}
156
+ @bullet_eager_loadings[record.class][record] ||= Set.new
157
+ @bullet_eager_loadings[record.class][record] << associations
158
+ end
159
+
160
+ result
161
+ end
162
+ end
163
+ )
164
+
165
+ ::ActiveRecord::Associations::Association.prepend(
166
+ Module.new do
167
+ def inversed_from(record)
168
+ if Bullet.start?
169
+ Bullet::Detector::NPlusOneQuery.add_inversed_object(owner, reflection.name)
170
+ end
171
+ super
172
+ end
173
+ end
174
+ )
175
+
176
+ ::ActiveRecord::Associations::CollectionAssociation.prepend(
177
+ Module.new do
178
+ def load_target
179
+ records = super
180
+
181
+ if Bullet.start?
182
+ if is_a? ::ActiveRecord::Associations::ThroughAssociation
183
+ association = owner.association(reflection.through_reflection.name)
184
+ if association.loaded?
185
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
186
+ Array.wrap(association.target).each do |through_record|
187
+ Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
188
+ end
189
+ end
190
+
191
+ if reflection.through_reflection != through_reflection
192
+ Bullet::Detector::NPlusOneQuery.call_association(owner, through_reflection.name)
193
+ end
194
+ end
195
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
196
+ if records.first.class.name !~ /^HABTM_/
197
+ if records.size > 1
198
+ Bullet::Detector::NPlusOneQuery.add_possible_objects(records)
199
+ Bullet::Detector::CounterCache.add_possible_objects(records)
200
+ elsif records.size == 1
201
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(records.first)
202
+ Bullet::Detector::CounterCache.add_impossible_object(records.first)
203
+ end
204
+ end
205
+ end
206
+ records
207
+ end
208
+
209
+ def empty?
210
+ if Bullet.start? && !reflection.has_cached_counter?
211
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
212
+ end
213
+ super
214
+ end
215
+
216
+ def include?(object)
217
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name) if Bullet.start?
218
+ super
219
+ end
220
+ end
221
+ )
222
+
223
+ ::ActiveRecord::Associations::SingularAssociation.prepend(
224
+ Module.new do
225
+ # call has_one and belongs_to associations
226
+ def reader
227
+ result = super
228
+
229
+ if Bullet.start?
230
+ if owner.class.name !~ /^HABTM_/
231
+ if is_a? ::ActiveRecord::Associations::ThroughAssociation
232
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
233
+ association = owner.association(reflection.through_reflection.name)
234
+ Array.wrap(association.target).each do |through_record|
235
+ Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
236
+ end
237
+
238
+ if reflection.through_reflection != through_reflection
239
+ Bullet::Detector::NPlusOneQuery.call_association(owner, through_reflection.name)
240
+ end
241
+ end
242
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
243
+
244
+ if Bullet::Detector::NPlusOneQuery.impossible?(owner)
245
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(result) if result
246
+ else
247
+ Bullet::Detector::NPlusOneQuery.add_possible_objects(result) if result
248
+ end
249
+ end
250
+ end
251
+ result
252
+ end
253
+ end
254
+ )
255
+
256
+ ::ActiveRecord::Associations::HasManyAssociation.prepend(
257
+ Module.new do
258
+ def empty?
259
+ result = super
260
+ if Bullet.start? && !reflection.has_cached_counter?
261
+ Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
262
+ end
263
+ result
264
+ end
265
+
266
+ def count_records
267
+ result = reflection.has_cached_counter?
268
+ if Bullet.start? && !result && !is_a?(::ActiveRecord::Associations::ThroughAssociation)
269
+ Bullet::Detector::CounterCache.add_counter_cache(owner, reflection.name)
270
+ end
271
+ super
272
+ end
273
+ end
274
+ )
275
+ end
276
+ end
277
+ end
@@ -0,0 +1,64 @@
1
+ (function () {
2
+ var oldOpen = window.XMLHttpRequest.prototype.open;
3
+ var oldSend = window.XMLHttpRequest.prototype.send;
4
+
5
+ /**
6
+ * Return early if we've already extended prototype. This prevents
7
+ * "maximum call stack exceeded" errors when used with Turbolinks.
8
+ * See https://github.com/flyerhzm/bullet/issues/454
9
+ */
10
+ if (isBulletInitiated()) return;
11
+
12
+ function isBulletInitiated() {
13
+ return oldOpen.name == "bulletXHROpen" && oldSend.name == "bulletXHRSend";
14
+ }
15
+ function bulletXHROpen(_, url) {
16
+ this._storedUrl = url;
17
+ return Reflect.apply(oldOpen, this, arguments);
18
+ }
19
+ function bulletXHRSend() {
20
+ if (this.onload) {
21
+ this._storedOnload = this.onload;
22
+ }
23
+ this.onload = null;
24
+ this.addEventListener("load", bulletXHROnload);
25
+ return Reflect.apply(oldSend, this, arguments);
26
+ }
27
+ function bulletXHROnload() {
28
+ if (
29
+ this._storedUrl.startsWith(window.location.protocol + "//" + window.location.host) ||
30
+ !this._storedUrl.startsWith("http") // For relative paths
31
+ ) {
32
+ var bulletFooterText = this.getResponseHeader("X-bullet-footer-text");
33
+ if (bulletFooterText) {
34
+ setTimeout(function () {
35
+ var oldHtml = document.querySelector("#bullet-footer").innerHTML.split("<br>");
36
+ var header = oldHtml[0];
37
+ oldHtml = oldHtml.slice(1, oldHtml.length);
38
+ var newHtml = oldHtml.concat(JSON.parse(bulletFooterText));
39
+ newHtml = newHtml.slice(newHtml.length - 10, newHtml.length); // rotate through 10 most recent
40
+ document.querySelector("#bullet-footer").innerHTML = `${header}<br>${newHtml.join("<br>")}`;
41
+ }, 0);
42
+ }
43
+ var bulletConsoleText = this.getResponseHeader("X-bullet-console-text");
44
+ if (bulletConsoleText && typeof console !== "undefined" && console.log) {
45
+ setTimeout(function () {
46
+ JSON.parse(bulletConsoleText).forEach((message) => {
47
+ if (console.groupCollapsed && console.groupEnd) {
48
+ console.groupCollapsed("Uniform Notifier");
49
+ console.log(message);
50
+ console.groupEnd();
51
+ } else {
52
+ console.log(message);
53
+ }
54
+ });
55
+ }, 0);
56
+ }
57
+ }
58
+ if (this._storedOnload) {
59
+ return Reflect.apply(this._storedOnload, this, arguments);
60
+ }
61
+ }
62
+ window.XMLHttpRequest.prototype.open = bulletXHROpen;
63
+ window.XMLHttpRequest.prototype.send = bulletXHRSend;
64
+ })();
@@ -3,51 +3,55 @@
3
3
  module Bullet
4
4
  module Dependency
5
5
  def mongoid?
6
- @mongoid ||= defined? ::Mongoid
6
+ @mongoid ||= defined?(::Mongoid)
7
7
  end
8
8
 
9
9
  def active_record?
10
- @active_record ||= defined? ::ActiveRecord
11
- end
12
-
13
- def rails?
14
- @rails ||= defined? ::Rails
10
+ @active_record ||= defined?(::ActiveRecord)
15
11
  end
16
12
 
17
13
  def active_record_version
18
- @active_record_version ||= begin
19
- if active_record40?
20
- 'active_record4'
21
- elsif active_record41?
22
- 'active_record41'
23
- elsif active_record42?
24
- 'active_record42'
25
- elsif active_record50?
26
- 'active_record5'
27
- elsif active_record51?
28
- 'active_record5'
29
- elsif active_record52?
30
- 'active_record52'
31
- else
32
- raise "Bullet does not support active_record #{::ActiveRecord::VERSION::STRING} yet"
33
- end
34
- end
14
+ @active_record_version ||=
15
+ begin
16
+ if active_record40?
17
+ 'active_record4'
18
+ elsif active_record41?
19
+ 'active_record41'
20
+ elsif active_record42?
21
+ 'active_record42'
22
+ elsif active_record50?
23
+ 'active_record5'
24
+ elsif active_record51?
25
+ 'active_record5'
26
+ elsif active_record52?
27
+ 'active_record52'
28
+ elsif active_record60?
29
+ 'active_record60'
30
+ elsif active_record61?
31
+ 'active_record61'
32
+ elsif active_record70?
33
+ 'active_record70'
34
+ else
35
+ raise "Bullet does not support active_record #{::ActiveRecord::VERSION::STRING} yet"
36
+ end
37
+ end
35
38
  end
36
39
 
37
40
  def mongoid_version
38
- @mongoid_version ||= begin
39
- if mongoid4x?
40
- 'mongoid4x'
41
- elsif mongoid5x?
42
- 'mongoid5x'
43
- elsif mongoid6x?
44
- 'mongoid6x'
45
- elsif mongoid7x?
46
- 'mongoid7x'
47
- else
48
- raise "Bullet does not support mongoid #{::Mongoid::VERSION} yet"
49
- end
50
- end
41
+ @mongoid_version ||=
42
+ begin
43
+ if mongoid4x?
44
+ 'mongoid4x'
45
+ elsif mongoid5x?
46
+ 'mongoid5x'
47
+ elsif mongoid6x?
48
+ 'mongoid6x'
49
+ elsif mongoid7x?
50
+ 'mongoid7x'
51
+ else
52
+ raise "Bullet does not support mongoid #{::Mongoid::VERSION} yet"
53
+ end
54
+ end
51
55
  end
52
56
 
53
57
  def active_record4?
@@ -58,6 +62,14 @@ module Bullet
58
62
  active_record? && ::ActiveRecord::VERSION::MAJOR == 5
59
63
  end
60
64
 
65
+ def active_record6?
66
+ active_record? && ::ActiveRecord::VERSION::MAJOR == 6
67
+ end
68
+
69
+ def active_record7?
70
+ active_record? && ::ActiveRecord::VERSION::MAJOR == 7
71
+ end
72
+
61
73
  def active_record40?
62
74
  active_record4? && ::ActiveRecord::VERSION::MINOR == 0
63
75
  end
@@ -82,6 +94,18 @@ module Bullet
82
94
  active_record5? && ::ActiveRecord::VERSION::MINOR == 2
83
95
  end
84
96
 
97
+ def active_record60?
98
+ active_record6? && ::ActiveRecord::VERSION::MINOR == 0
99
+ end
100
+
101
+ def active_record61?
102
+ active_record6? && ::ActiveRecord::VERSION::MINOR == 1
103
+ end
104
+
105
+ def active_record70?
106
+ active_record7? && ::ActiveRecord::VERSION::MINOR == 0
107
+ end
108
+
85
109
  def mongoid4x?
86
110
  mongoid? && ::Mongoid::VERSION =~ /\A4/
87
111
  end
@@ -3,22 +3,28 @@
3
3
  module Bullet
4
4
  module Detector
5
5
  class Association < Base
6
- class <<self
6
+ class << self
7
7
  def add_object_associations(object, associations)
8
8
  return unless Bullet.start?
9
9
  return if !Bullet.n_plus_one_query_enable? && !Bullet.unused_eager_loading_enable?
10
- return unless object.primary_key_value
10
+ return unless object.bullet_primary_key_value
11
11
 
12
- Bullet.debug('Detector::Association#add_object_associations', "object: #{object.bullet_key}, associations: #{associations}")
12
+ Bullet.debug(
13
+ 'Detector::Association#add_object_associations',
14
+ "object: #{object.bullet_key}, associations: #{associations}"
15
+ )
13
16
  object_associations.add(object.bullet_key, associations)
14
17
  end
15
18
 
16
19
  def add_call_object_associations(object, associations)
17
20
  return unless Bullet.start?
18
21
  return if !Bullet.n_plus_one_query_enable? && !Bullet.unused_eager_loading_enable?
19
- return unless object.primary_key_value
22
+ return unless object.bullet_primary_key_value
20
23
 
21
- Bullet.debug('Detector::Association#add_call_object_associations', "object: #{object.bullet_key}, associations: #{associations}")
24
+ Bullet.debug(
25
+ 'Detector::Association#add_call_object_associations',
26
+ "object: #{object.bullet_key}, associations: #{associations}"
27
+ )
22
28
  call_object_associations.add(object.bullet_key, associations)
23
29
  end
24
30
 
@@ -40,33 +46,33 @@ module Bullet
40
46
 
41
47
  private
42
48
 
43
- # object_associations keep the object relationships
44
- # that the object has many associations.
45
- # e.g. { "Post:1" => [:comments] }
46
- # the object_associations keep all associations that may be or may no be
47
- # unpreload associations or unused preload associations.
49
+ # object_associations keep the object relationships
50
+ # that the object has many associations.
51
+ # e.g. { "Post:1" => [:comments] }
52
+ # the object_associations keep all associations that may be or may no be
53
+ # unpreload associations or unused preload associations.
48
54
  def object_associations
49
55
  Thread.current[:bullet_object_associations]
50
56
  end
51
57
 
52
- # call_object_associations keep the object relationships
53
- # that object.associations is called.
54
- # e.g. { "Post:1" => [:comments] }
55
- # they are used to detect unused preload associations.
58
+ # call_object_associations keep the object relationships
59
+ # that object.associations is called.
60
+ # e.g. { "Post:1" => [:comments] }
61
+ # they are used to detect unused preload associations.
56
62
  def call_object_associations
57
63
  Thread.current[:bullet_call_object_associations]
58
64
  end
59
65
 
60
- # inversed_objects keeps object relationships
61
- # that association is inversed.
62
- # e.g. { "Comment:1" => ["post"] }
66
+ # inversed_objects keeps object relationships
67
+ # that association is inversed.
68
+ # e.g. { "Comment:1" => ["post"] }
63
69
  def inversed_objects
64
70
  Thread.current[:bullet_inversed_objects]
65
71
  end
66
72
 
67
- # eager_loadings keep the object relationships
68
- # that the associations are preloaded by find :include.
69
- # e.g. { ["Post:1", "Post:2"] => [:comments, :user] }
73
+ # eager_loadings keep the object relationships
74
+ # that the associations are preloaded by find :include.
75
+ # e.g. { ["Post:1", "Post:2"] => [:comments, :user] }
70
76
  def eager_loadings
71
77
  Thread.current[:bullet_eager_loadings]
72
78
  end
@@ -3,33 +3,37 @@
3
3
  module Bullet
4
4
  module Detector
5
5
  class CounterCache < Base
6
- class <<self
6
+ class << self
7
7
  def add_counter_cache(object, associations)
8
8
  return unless Bullet.start?
9
9
  return unless Bullet.counter_cache_enable?
10
- return unless object.primary_key_value
10
+ return unless object.bullet_primary_key_value
11
11
 
12
- Bullet.debug('Detector::CounterCache#add_counter_cache', "object: #{object.bullet_key}, associations: #{associations}")
13
- if conditions_met?(object, associations)
14
- create_notification object.class.to_s, associations
15
- end
12
+ Bullet.debug(
13
+ 'Detector::CounterCache#add_counter_cache',
14
+ "object: #{object.bullet_key}, associations: #{associations}"
15
+ )
16
+ create_notification object.class.to_s, associations if conditions_met?(object, associations)
16
17
  end
17
18
 
18
19
  def add_possible_objects(object_or_objects)
19
20
  return unless Bullet.start?
20
21
  return unless Bullet.counter_cache_enable?
21
22
 
22
- objects = Array(object_or_objects)
23
- return if objects.map(&:primary_key_value).compact.empty?
23
+ objects = Array.wrap(object_or_objects)
24
+ return if objects.map(&:bullet_primary_key_value).compact.empty?
24
25
 
25
- Bullet.debug('Detector::CounterCache#add_possible_objects', "objects: #{objects.map(&:bullet_key).join(', ')}")
26
+ Bullet.debug(
27
+ 'Detector::CounterCache#add_possible_objects',
28
+ "objects: #{objects.map(&:bullet_key).join(', ')}"
29
+ )
26
30
  objects.each { |object| possible_objects.add object.bullet_key }
27
31
  end
28
32
 
29
33
  def add_impossible_object(object)
30
34
  return unless Bullet.start?
31
35
  return unless Bullet.counter_cache_enable?
32
- return unless object.primary_key_value
36
+ return unless object.bullet_primary_key_value
33
37
 
34
38
  Bullet.debug('Detector::CounterCache#add_impossible_object', "object: #{object.bullet_key}")
35
39
  impossible_objects.add object.bullet_key
@@ -50,7 +54,7 @@ module Bullet
50
54
  private
51
55
 
52
56
  def create_notification(klazz, associations)
53
- notify_associations = Array(associations) - Bullet.get_whitelist_associations(:counter_cache, klazz)
57
+ notify_associations = Array.wrap(associations) - Bullet.get_safelist_associations(:counter_cache, klazz)
54
58
 
55
59
  if notify_associations.present?
56
60
  notice = Bullet::Notification::CounterCache.new klazz, notify_associations