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.
- checksums.yaml +5 -5
- data/.travis.yml +22 -1
- data/CHANGELOG.md +49 -12
- data/Gemfile.mongoid-7.0 +15 -0
- data/Gemfile.rails-4.0 +1 -1
- data/Gemfile.rails-4.1 +1 -1
- data/Gemfile.rails-4.2 +1 -1
- data/Gemfile.rails-5.0 +1 -1
- data/Gemfile.rails-5.1 +1 -1
- data/Gemfile.rails-5.2 +2 -2
- data/Gemfile.rails-6.0 +15 -0
- data/Gemfile.rails-6.1 +15 -0
- data/README.md +38 -13
- data/Rakefile +1 -1
- data/bullet.gemspec +8 -3
- data/lib/bullet.rb +50 -22
- data/lib/bullet/active_job.rb +13 -0
- data/lib/bullet/active_record4.rb +12 -35
- data/lib/bullet/active_record41.rb +10 -30
- data/lib/bullet/active_record42.rb +12 -27
- data/lib/bullet/active_record5.rb +197 -177
- data/lib/bullet/active_record52.rb +191 -166
- data/lib/bullet/active_record60.rb +278 -0
- data/lib/bullet/active_record61.rb +278 -0
- data/lib/bullet/bullet_xhr.js +63 -0
- data/lib/bullet/dependency.rb +54 -34
- data/lib/bullet/detector/association.rb +26 -20
- data/lib/bullet/detector/base.rb +1 -2
- data/lib/bullet/detector/counter_cache.rb +14 -9
- data/lib/bullet/detector/n_plus_one_query.rb +27 -17
- data/lib/bullet/detector/unused_eager_loading.rb +7 -3
- data/lib/bullet/ext/object.rb +5 -3
- data/lib/bullet/ext/string.rb +1 -1
- data/lib/bullet/mongoid4x.rb +4 -7
- data/lib/bullet/mongoid5x.rb +4 -7
- data/lib/bullet/mongoid6x.rb +8 -11
- data/lib/bullet/mongoid7x.rb +57 -0
- data/lib/bullet/notification/base.rb +15 -19
- data/lib/bullet/notification/n_plus_one_query.rb +2 -4
- data/lib/bullet/notification/unused_eager_loading.rb +2 -4
- data/lib/bullet/rack.rb +54 -28
- data/lib/bullet/stack_trace_filter.rb +39 -30
- data/lib/bullet/version.rb +1 -1
- data/lib/generators/bullet/install_generator.rb +26 -26
- data/perf/benchmark.rb +8 -14
- data/spec/bullet/detector/counter_cache_spec.rb +6 -6
- data/spec/bullet/detector/n_plus_one_query_spec.rb +30 -3
- data/spec/bullet/detector/unused_eager_loading_spec.rb +19 -6
- data/spec/bullet/ext/object_spec.rb +9 -4
- data/spec/bullet/notification/base_spec.rb +1 -3
- data/spec/bullet/notification/n_plus_one_query_spec.rb +16 -3
- data/spec/bullet/notification/unused_eager_loading_spec.rb +5 -1
- data/spec/bullet/rack_spec.rb +140 -5
- data/spec/bullet/registry/association_spec.rb +2 -2
- data/spec/bullet/registry/base_spec.rb +1 -1
- data/spec/bullet_spec.rb +10 -29
- data/spec/integration/active_record/association_spec.rb +122 -118
- data/spec/integration/counter_cache_spec.rb +11 -31
- data/spec/integration/mongoid/association_spec.rb +18 -32
- data/spec/models/attachment.rb +5 -0
- data/spec/models/client.rb +2 -0
- data/spec/models/firm.rb +1 -0
- data/spec/models/folder.rb +1 -2
- data/spec/models/group.rb +3 -0
- data/spec/models/page.rb +1 -2
- data/spec/models/post.rb +15 -0
- data/spec/models/submission.rb +1 -0
- data/spec/models/user.rb +1 -0
- data/spec/models/writer.rb +1 -2
- data/spec/spec_helper.rb +6 -10
- data/spec/support/bullet_ext.rb +8 -9
- data/spec/support/mongo_seed.rb +2 -16
- data/spec/support/sqlite_seed.rb +17 -2
- data/test.sh +2 -0
- data/update.sh +1 -0
- metadata +24 -11
@@ -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
|
52
|
-
|
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 :
|
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
|
-
|
78
|
-
|
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
|
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
|
54
|
-
|
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 :
|
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
|
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
|
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
|
48
|
-
|
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 :
|
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
|
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
|
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
|
6
|
-
|
7
|
-
|
8
|
-
|
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(
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
if
|
28
|
-
if result.
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
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
|
-
|
37
|
+
)
|
43
38
|
|
44
39
|
::ActiveRecord::Base.prepend(SaveWithBulletSupport)
|
45
40
|
|
46
|
-
::ActiveRecord::Relation.prepend(
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
if
|
53
|
-
if result.
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
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
|
-
|
65
|
-
|
66
|
-
::ActiveRecord::Associations::Preloader.prepend(
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
records.
|
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
|
-
|
80
|
-
|
81
|
-
::ActiveRecord::FinderMethods.prepend(
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
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
|
-
|
90
|
+
records
|
92
91
|
end
|
93
|
-
records
|
94
92
|
end
|
95
|
-
|
93
|
+
)
|
96
94
|
|
97
|
-
::ActiveRecord::Associations::JoinDependency.prepend(
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
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
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
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
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
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
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
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
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
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
|
-
|
146
|
-
|
154
|
+
# call join associations
|
155
|
+
def construct_model(record, node, row, model_cache, id, aliases)
|
156
|
+
result = super
|
147
157
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
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
|
-
|
167
|
+
result
|
168
|
+
end
|
162
169
|
end
|
163
|
-
|
164
|
-
|
165
|
-
::ActiveRecord::Associations::CollectionAssociation.prepend(
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
if
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
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
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
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
|
-
|
192
|
-
|
193
|
-
|
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
|
-
|
199
|
-
|
200
|
-
|
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
|
-
|
205
|
-
|
206
|
-
::ActiveRecord::Associations::SingularAssociation.prepend(
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
if
|
214
|
-
Bullet::Detector::NPlusOneQuery.
|
215
|
-
|
216
|
-
Bullet::Detector::NPlusOneQuery.
|
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
|
-
|
240
|
+
)
|
223
241
|
|
224
|
-
::ActiveRecord::Associations::HasManyAssociation.prepend(
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
Bullet
|
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
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
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
|
-
|
260
|
+
)
|
241
261
|
end
|
242
262
|
end
|
243
263
|
end
|