bullet 5.7.5 → 6.1.4

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