bullet 4.14.4 → 4.14.6
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 +4 -4
- data/.travis.yml +26 -1
- data/CHANGELOG.md +14 -2
- data/Gemfile.mongoid +0 -2
- data/Gemfile.mongoid-2.4 +0 -2
- data/Gemfile.mongoid-2.5 +0 -2
- data/Gemfile.mongoid-2.6 +0 -2
- data/Gemfile.mongoid-2.7 +0 -2
- data/Gemfile.mongoid-2.8 +0 -2
- data/Gemfile.mongoid-3.0 +0 -2
- data/Gemfile.mongoid-3.1 +0 -2
- data/Gemfile.mongoid-4.0 +0 -2
- data/Gemfile.rails-3.1 +0 -2
- data/Gemfile.rails-3.2 +0 -2
- data/Gemfile.rails-4.0 +0 -2
- data/Gemfile.rails-4.1 +0 -2
- data/Gemfile.rails-4.2 +0 -2
- data/README.md +8 -1
- data/bullet.gemspec +1 -1
- data/lib/bullet/active_record3.rb +63 -35
- data/lib/bullet/active_record3x.rb +55 -33
- data/lib/bullet/active_record4.rb +51 -31
- data/lib/bullet/active_record41.rb +53 -32
- data/lib/bullet/active_record42.rb +80 -50
- data/lib/bullet/detector/association.rb +16 -16
- data/lib/bullet/detector/counter_cache.rb +13 -13
- data/lib/bullet/detector/n_plus_one_query.rb +30 -27
- data/lib/bullet/notification/n_plus_one_query.rb +6 -0
- data/lib/bullet/rack.rb +3 -5
- data/lib/bullet/version.rb +1 -1
- data/lib/bullet.rb +12 -7
- data/spec/bullet/detector/counter_cache_spec.rb +8 -8
- data/spec/bullet/detector/n_plus_one_query_spec.rb +27 -27
- data/spec/bullet/rack_spec.rb +2 -2
- data/spec/integration/active_record3/association_spec.rb +9 -0
- data/spec/integration/active_record4/association_spec.rb +9 -0
- metadata +7 -7
|
@@ -8,12 +8,14 @@ module Bullet
|
|
|
8
8
|
# if select only one object, then the only one object has impossible to cause N+1 query.
|
|
9
9
|
def to_a
|
|
10
10
|
records = origin_to_a
|
|
11
|
-
if
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
if Bullet.start?
|
|
12
|
+
if records.size > 1
|
|
13
|
+
Bullet::Detector::NPlusOneQuery.add_possible_objects(records)
|
|
14
|
+
Bullet::Detector::CounterCache.add_possible_objects(records)
|
|
15
|
+
elsif records.size == 1
|
|
16
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(records.first)
|
|
17
|
+
Bullet::Detector::CounterCache.add_impossible_object(records.first)
|
|
18
|
+
end
|
|
17
19
|
end
|
|
18
20
|
records
|
|
19
21
|
end
|
|
@@ -25,12 +27,14 @@ module Bullet
|
|
|
25
27
|
alias_method :origin_initialize, :initialize
|
|
26
28
|
def initialize(records, associations, preload_scope = nil)
|
|
27
29
|
origin_initialize(records, associations, preload_scope)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
if Bullet.start?
|
|
31
|
+
records = [records].flatten.compact.uniq
|
|
32
|
+
return if records.empty?
|
|
33
|
+
records.each do |record|
|
|
34
|
+
Bullet::Detector::Association.add_object_associations(record, associations)
|
|
35
|
+
end
|
|
36
|
+
Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, associations)
|
|
32
37
|
end
|
|
33
|
-
Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, associations)
|
|
34
38
|
end
|
|
35
39
|
end
|
|
36
40
|
|
|
@@ -39,11 +43,13 @@ module Bullet
|
|
|
39
43
|
alias_method :origin_find_with_associations, :find_with_associations
|
|
40
44
|
def find_with_associations
|
|
41
45
|
records = origin_find_with_associations
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
if Bullet.start?
|
|
47
|
+
associations = (eager_load_values + includes_values).uniq
|
|
48
|
+
records.each do |record|
|
|
49
|
+
Bullet::Detector::Association.add_object_associations(record, associations)
|
|
50
|
+
end
|
|
51
|
+
Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, associations)
|
|
45
52
|
end
|
|
46
|
-
Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, associations)
|
|
47
53
|
records
|
|
48
54
|
end
|
|
49
55
|
end
|
|
@@ -56,9 +62,11 @@ module Bullet
|
|
|
56
62
|
@bullet_eager_loadings = {}
|
|
57
63
|
records = origin_instantiate(rows)
|
|
58
64
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
65
|
+
if Bullet.start?
|
|
66
|
+
@bullet_eager_loadings.each do |klazz, eager_loadings_hash|
|
|
67
|
+
objects = eager_loadings_hash.keys
|
|
68
|
+
Bullet::Detector::UnusedEagerLoading.add_eager_loadings(objects, eager_loadings_hash[objects.first].to_a)
|
|
69
|
+
end
|
|
62
70
|
end
|
|
63
71
|
records
|
|
64
72
|
end
|
|
@@ -67,12 +75,14 @@ module Bullet
|
|
|
67
75
|
def construct_association(record, join, row)
|
|
68
76
|
result = origin_construct_association(record, join, row)
|
|
69
77
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
78
|
+
if Bullet.start?
|
|
79
|
+
associations = join.reflection.name
|
|
80
|
+
Bullet::Detector::Association.add_object_associations(record, associations)
|
|
81
|
+
Bullet::Detector::NPlusOneQuery.call_association(record, associations)
|
|
82
|
+
@bullet_eager_loadings[record.class] ||= {}
|
|
83
|
+
@bullet_eager_loadings[record.class][record] ||= Set.new
|
|
84
|
+
@bullet_eager_loadings[record.class][record] << associations
|
|
85
|
+
end
|
|
76
86
|
|
|
77
87
|
result
|
|
78
88
|
end
|
|
@@ -82,19 +92,25 @@ module Bullet
|
|
|
82
92
|
# call one to many associations
|
|
83
93
|
alias_method :origin_load_target, :load_target
|
|
84
94
|
def load_target
|
|
85
|
-
Bullet
|
|
95
|
+
if Bullet.start?
|
|
96
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
97
|
+
end
|
|
86
98
|
origin_load_target
|
|
87
99
|
end
|
|
88
100
|
|
|
89
101
|
alias_method :origin_empty?, :empty?
|
|
90
102
|
def empty?
|
|
91
|
-
Bullet
|
|
103
|
+
if Bullet.start?
|
|
104
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
105
|
+
end
|
|
92
106
|
origin_empty?
|
|
93
107
|
end
|
|
94
108
|
|
|
95
109
|
alias_method :origin_include?, :include?
|
|
96
110
|
def include?(object)
|
|
97
|
-
Bullet
|
|
111
|
+
if Bullet.start?
|
|
112
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
113
|
+
end
|
|
98
114
|
origin_include?(object)
|
|
99
115
|
end
|
|
100
116
|
end
|
|
@@ -104,9 +120,11 @@ module Bullet
|
|
|
104
120
|
alias_method :origin_reader, :reader
|
|
105
121
|
def reader(force_reload = false)
|
|
106
122
|
result = origin_reader(force_reload)
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
123
|
+
if Bullet.start?
|
|
124
|
+
unless @inversed
|
|
125
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
126
|
+
Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
|
|
127
|
+
end
|
|
110
128
|
end
|
|
111
129
|
result
|
|
112
130
|
end
|
|
@@ -117,7 +135,9 @@ module Bullet
|
|
|
117
135
|
|
|
118
136
|
def has_cached_counter?(reflection = reflection())
|
|
119
137
|
result = origin_has_cached_counter?(reflection)
|
|
120
|
-
Bullet
|
|
138
|
+
if Bullet.start?
|
|
139
|
+
Bullet::Detector::CounterCache.add_counter_cache(owner, reflection.name) unless result
|
|
140
|
+
end
|
|
121
141
|
result
|
|
122
142
|
end
|
|
123
143
|
end
|
|
@@ -8,13 +8,15 @@ module Bullet
|
|
|
8
8
|
# if select only one object, then the only one object has impossible to cause N+1 query.
|
|
9
9
|
def to_a
|
|
10
10
|
records = origin_to_a
|
|
11
|
-
if
|
|
12
|
-
if records.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
if Bullet.start?
|
|
12
|
+
if records.first.class.name !~ /^HABTM_/
|
|
13
|
+
if records.size > 1
|
|
14
|
+
Bullet::Detector::NPlusOneQuery.add_possible_objects(records)
|
|
15
|
+
Bullet::Detector::CounterCache.add_possible_objects(records)
|
|
16
|
+
elsif records.size == 1
|
|
17
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(records.first)
|
|
18
|
+
Bullet::Detector::CounterCache.add_impossible_object(records.first)
|
|
19
|
+
end
|
|
18
20
|
end
|
|
19
21
|
end
|
|
20
22
|
records
|
|
@@ -25,12 +27,14 @@ module Bullet
|
|
|
25
27
|
alias_method :origin_preloaders_on, :preloaders_on
|
|
26
28
|
|
|
27
29
|
def preloaders_on(association, records, scope)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
records.
|
|
31
|
-
|
|
30
|
+
if Bullet.start?
|
|
31
|
+
records.compact!
|
|
32
|
+
if records.first.class.name !~ /^HABTM_/
|
|
33
|
+
records.each do |record|
|
|
34
|
+
Bullet::Detector::Association.add_object_associations(record, association)
|
|
35
|
+
end
|
|
36
|
+
Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, association)
|
|
32
37
|
end
|
|
33
|
-
Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, association)
|
|
34
38
|
end
|
|
35
39
|
origin_preloaders_on(association, records, scope)
|
|
36
40
|
end
|
|
@@ -40,12 +44,15 @@ module Bullet
|
|
|
40
44
|
# add includes in scope
|
|
41
45
|
alias_method :origin_find_with_associations, :find_with_associations
|
|
42
46
|
def find_with_associations
|
|
47
|
+
return origin_find_with_associations { |r| yield r } if block_given?
|
|
43
48
|
records = origin_find_with_associations
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
49
|
+
if Bullet.start?
|
|
50
|
+
associations = (eager_load_values + includes_values).uniq
|
|
51
|
+
records.each do |record|
|
|
52
|
+
Bullet::Detector::Association.add_object_associations(record, associations)
|
|
53
|
+
end
|
|
54
|
+
Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, associations)
|
|
47
55
|
end
|
|
48
|
-
Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, associations)
|
|
49
56
|
records
|
|
50
57
|
end
|
|
51
58
|
end
|
|
@@ -58,9 +65,11 @@ module Bullet
|
|
|
58
65
|
@bullet_eager_loadings = {}
|
|
59
66
|
records = origin_instantiate(result_set, aliases)
|
|
60
67
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
68
|
+
if Bullet.start?
|
|
69
|
+
@bullet_eager_loadings.each do |klazz, eager_loadings_hash|
|
|
70
|
+
objects = eager_loadings_hash.keys
|
|
71
|
+
Bullet::Detector::UnusedEagerLoading.add_eager_loadings(objects, eager_loadings_hash[objects.first].to_a)
|
|
72
|
+
end
|
|
64
73
|
end
|
|
65
74
|
records
|
|
66
75
|
end
|
|
@@ -69,12 +78,14 @@ module Bullet
|
|
|
69
78
|
def construct_model(record, node, row, model_cache, id, aliases)
|
|
70
79
|
result = origin_construct_model(record, node, row, model_cache, id, aliases)
|
|
71
80
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
81
|
+
if Bullet.start?
|
|
82
|
+
associations = node.reflection.name
|
|
83
|
+
Bullet::Detector::Association.add_object_associations(record, associations)
|
|
84
|
+
Bullet::Detector::NPlusOneQuery.call_association(record, associations)
|
|
85
|
+
@bullet_eager_loadings[record.class] ||= {}
|
|
86
|
+
@bullet_eager_loadings[record.class][record] ||= Set.new
|
|
87
|
+
@bullet_eager_loadings[record.class][record] << associations
|
|
88
|
+
end
|
|
78
89
|
|
|
79
90
|
result
|
|
80
91
|
end
|
|
@@ -84,19 +95,25 @@ module Bullet
|
|
|
84
95
|
# call one to many associations
|
|
85
96
|
alias_method :origin_load_target, :load_target
|
|
86
97
|
def load_target
|
|
87
|
-
Bullet
|
|
98
|
+
if Bullet.start?
|
|
99
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name) unless @inversed
|
|
100
|
+
end
|
|
88
101
|
origin_load_target
|
|
89
102
|
end
|
|
90
103
|
|
|
91
104
|
alias_method :origin_empty?, :empty?
|
|
92
105
|
def empty?
|
|
93
|
-
Bullet
|
|
106
|
+
if Bullet.start?
|
|
107
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
108
|
+
end
|
|
94
109
|
origin_empty?
|
|
95
110
|
end
|
|
96
111
|
|
|
97
112
|
alias_method :origin_include?, :include?
|
|
98
113
|
def include?(object)
|
|
99
|
-
Bullet
|
|
114
|
+
if Bullet.start?
|
|
115
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
116
|
+
end
|
|
100
117
|
origin_include?(object)
|
|
101
118
|
end
|
|
102
119
|
end
|
|
@@ -106,9 +123,11 @@ module Bullet
|
|
|
106
123
|
alias_method :origin_reader, :reader
|
|
107
124
|
def reader(force_reload = false)
|
|
108
125
|
result = origin_reader(force_reload)
|
|
109
|
-
if
|
|
110
|
-
|
|
111
|
-
|
|
126
|
+
if Bullet.start?
|
|
127
|
+
if @owner.class.name !~ /^HABTM_/ && !@inversed
|
|
128
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
129
|
+
Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
|
|
130
|
+
end
|
|
112
131
|
end
|
|
113
132
|
result
|
|
114
133
|
end
|
|
@@ -119,7 +138,9 @@ module Bullet
|
|
|
119
138
|
|
|
120
139
|
def has_cached_counter?(reflection = reflection())
|
|
121
140
|
result = origin_has_cached_counter?(reflection)
|
|
122
|
-
Bullet
|
|
141
|
+
if Bullet.start?
|
|
142
|
+
Bullet::Detector::CounterCache.add_counter_cache(owner, reflection.name) unless result
|
|
143
|
+
end
|
|
123
144
|
result
|
|
124
145
|
end
|
|
125
146
|
end
|
|
@@ -7,12 +7,14 @@ module Bullet
|
|
|
7
7
|
alias_method :origin_find, :find
|
|
8
8
|
def find(*args)
|
|
9
9
|
result = origin_find(*args)
|
|
10
|
-
if
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
if Bullet.start?
|
|
11
|
+
if result.is_a? Array
|
|
12
|
+
Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
|
|
13
|
+
Bullet::Detector::CounterCache.add_possible_objects(result)
|
|
14
|
+
elsif result.is_a? ::ActiveRecord::Base
|
|
15
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(result)
|
|
16
|
+
Bullet::Detector::CounterCache.add_impossible_object(result)
|
|
17
|
+
end
|
|
16
18
|
end
|
|
17
19
|
result
|
|
18
20
|
end
|
|
@@ -25,13 +27,15 @@ module Bullet
|
|
|
25
27
|
# if select only one object, then the only one object has impossible to cause N+1 query.
|
|
26
28
|
def to_a
|
|
27
29
|
records = origin_to_a
|
|
28
|
-
if
|
|
29
|
-
if records.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
if Bullet.start?
|
|
31
|
+
if records.first.class.name !~ /^HABTM_/
|
|
32
|
+
if records.size > 1
|
|
33
|
+
Bullet::Detector::NPlusOneQuery.add_possible_objects(records)
|
|
34
|
+
Bullet::Detector::CounterCache.add_possible_objects(records)
|
|
35
|
+
elsif records.size == 1
|
|
36
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(records.first)
|
|
37
|
+
Bullet::Detector::CounterCache.add_impossible_object(records.first)
|
|
38
|
+
end
|
|
35
39
|
end
|
|
36
40
|
end
|
|
37
41
|
records
|
|
@@ -42,12 +46,14 @@ module Bullet
|
|
|
42
46
|
alias_method :origin_preloaders_on, :preloaders_on
|
|
43
47
|
|
|
44
48
|
def preloaders_on(association, records, scope)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
records.
|
|
48
|
-
|
|
49
|
+
if Bullet.start?
|
|
50
|
+
records.compact!
|
|
51
|
+
if records.first.class.name !~ /^HABTM_/
|
|
52
|
+
records.each do |record|
|
|
53
|
+
Bullet::Detector::Association.add_object_associations(record, association)
|
|
54
|
+
end
|
|
55
|
+
Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, association)
|
|
49
56
|
end
|
|
50
|
-
Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, association)
|
|
51
57
|
end
|
|
52
58
|
origin_preloaders_on(association, records, scope)
|
|
53
59
|
end
|
|
@@ -57,12 +63,15 @@ module Bullet
|
|
|
57
63
|
# add includes in scope
|
|
58
64
|
alias_method :origin_find_with_associations, :find_with_associations
|
|
59
65
|
def find_with_associations
|
|
66
|
+
return origin_find_with_associations { |r| yield r } if block_given?
|
|
60
67
|
records = origin_find_with_associations
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
68
|
+
if Bullet.start?
|
|
69
|
+
associations = (eager_load_values + includes_values).uniq
|
|
70
|
+
records.each do |record|
|
|
71
|
+
Bullet::Detector::Association.add_object_associations(record, associations)
|
|
72
|
+
end
|
|
73
|
+
Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, associations)
|
|
64
74
|
end
|
|
65
|
-
Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, associations)
|
|
66
75
|
records
|
|
67
76
|
end
|
|
68
77
|
end
|
|
@@ -75,9 +84,11 @@ module Bullet
|
|
|
75
84
|
@bullet_eager_loadings = {}
|
|
76
85
|
records = origin_instantiate(result_set, aliases)
|
|
77
86
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
87
|
+
if Bullet.start?
|
|
88
|
+
@bullet_eager_loadings.each do |klazz, eager_loadings_hash|
|
|
89
|
+
objects = eager_loadings_hash.keys
|
|
90
|
+
Bullet::Detector::UnusedEagerLoading.add_eager_loadings(objects, eager_loadings_hash[objects.first].to_a)
|
|
91
|
+
end
|
|
81
92
|
end
|
|
82
93
|
records
|
|
83
94
|
end
|
|
@@ -86,12 +97,14 @@ module Bullet
|
|
|
86
97
|
def construct_model(record, node, row, model_cache, id, aliases)
|
|
87
98
|
result = origin_construct_model(record, node, row, model_cache, id, aliases)
|
|
88
99
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
100
|
+
if Bullet.start?
|
|
101
|
+
associations = node.reflection.name
|
|
102
|
+
Bullet::Detector::Association.add_object_associations(record, associations)
|
|
103
|
+
Bullet::Detector::NPlusOneQuery.call_association(record, associations)
|
|
104
|
+
@bullet_eager_loadings[record.class] ||= {}
|
|
105
|
+
@bullet_eager_loadings[record.class][record] ||= Set.new
|
|
106
|
+
@bullet_eager_loadings[record.class][record] << associations
|
|
107
|
+
end
|
|
95
108
|
|
|
96
109
|
result
|
|
97
110
|
end
|
|
@@ -101,16 +114,18 @@ module Bullet
|
|
|
101
114
|
# call one to many associations
|
|
102
115
|
alias_method :origin_load_target, :load_target
|
|
103
116
|
def load_target
|
|
104
|
-
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name) unless @inversed
|
|
105
117
|
records = origin_load_target
|
|
106
118
|
|
|
107
|
-
if
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
119
|
+
if Bullet.start?
|
|
120
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name) unless @inversed
|
|
121
|
+
if records.first.class.name !~ /^HABTM_/
|
|
122
|
+
if records.size > 1
|
|
123
|
+
Bullet::Detector::NPlusOneQuery.add_possible_objects(records)
|
|
124
|
+
Bullet::Detector::CounterCache.add_possible_objects(records)
|
|
125
|
+
elsif records.size == 1
|
|
126
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(records.first)
|
|
127
|
+
Bullet::Detector::CounterCache.add_impossible_object(records.first)
|
|
128
|
+
end
|
|
114
129
|
end
|
|
115
130
|
end
|
|
116
131
|
records
|
|
@@ -118,13 +133,17 @@ module Bullet
|
|
|
118
133
|
|
|
119
134
|
alias_method :origin_empty?, :empty?
|
|
120
135
|
def empty?
|
|
121
|
-
Bullet
|
|
136
|
+
if Bullet.start?
|
|
137
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
138
|
+
end
|
|
122
139
|
origin_empty?
|
|
123
140
|
end
|
|
124
141
|
|
|
125
142
|
alias_method :origin_include?, :include?
|
|
126
143
|
def include?(object)
|
|
127
|
-
Bullet
|
|
144
|
+
if Bullet.start?
|
|
145
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
146
|
+
end
|
|
128
147
|
origin_include?(object)
|
|
129
148
|
end
|
|
130
149
|
end
|
|
@@ -134,12 +153,19 @@ module Bullet
|
|
|
134
153
|
alias_method :origin_reader, :reader
|
|
135
154
|
def reader(force_reload = false)
|
|
136
155
|
result = origin_reader(force_reload)
|
|
137
|
-
if
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
156
|
+
if Bullet.start?
|
|
157
|
+
if @owner.class.name !~ /^HABTM_/ && !@inversed
|
|
158
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
159
|
+
if Bullet::Detector::NPlusOneQuery.impossible?(@owner)
|
|
160
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(result)
|
|
161
|
+
else
|
|
162
|
+
Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
if ::ActiveRecord::Reflection::HasOneReflection === @reflection && result
|
|
166
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
167
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(result)
|
|
168
|
+
end
|
|
143
169
|
end
|
|
144
170
|
result
|
|
145
171
|
end
|
|
@@ -151,15 +177,19 @@ module Bullet
|
|
|
151
177
|
Thread.current[:bullet_collection_empty] = true
|
|
152
178
|
result = origin_many_empty?
|
|
153
179
|
Thread.current[:bullet_collection_empty] = nil
|
|
154
|
-
Bullet
|
|
180
|
+
if Bullet.start?
|
|
181
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
182
|
+
end
|
|
155
183
|
result
|
|
156
184
|
end
|
|
157
185
|
|
|
158
186
|
alias_method :origin_has_cached_counter?, :has_cached_counter?
|
|
159
187
|
def has_cached_counter?(reflection = reflection())
|
|
160
188
|
result = origin_has_cached_counter?(reflection)
|
|
161
|
-
if
|
|
162
|
-
|
|
189
|
+
if Bullet.start?
|
|
190
|
+
if !result && !Thread.current[:bullet_collection_empty]
|
|
191
|
+
Bullet::Detector::CounterCache.add_counter_cache(owner, reflection.name)
|
|
192
|
+
end
|
|
163
193
|
end
|
|
164
194
|
result
|
|
165
195
|
end
|
|
@@ -20,6 +20,22 @@ module Bullet
|
|
|
20
20
|
call_object_associations.add(object.bullet_key, associations)
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
+
# possible_objects keep the class to object relationships
|
|
24
|
+
# that the objects may cause N+1 query.
|
|
25
|
+
# e.g. { Post => ["Post:1", "Post:2"] }
|
|
26
|
+
def possible_objects
|
|
27
|
+
Thread.current[:bullet_possible_objects]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# impossible_objects keep the class to objects relationships
|
|
31
|
+
# that the objects may not cause N+1 query.
|
|
32
|
+
# e.g. { Post => ["Post:1", "Post:2"] }
|
|
33
|
+
# if find collection returns only one object, then the object is impossible object,
|
|
34
|
+
# impossible_objects are used to avoid treating 1+1 query to N+1 query.
|
|
35
|
+
def impossible_objects
|
|
36
|
+
Thread.current[:bullet_impossible_objects]
|
|
37
|
+
end
|
|
38
|
+
|
|
23
39
|
private
|
|
24
40
|
# object_associations keep the object relationships
|
|
25
41
|
# that the object has many associations.
|
|
@@ -38,22 +54,6 @@ module Bullet
|
|
|
38
54
|
Thread.current[:bullet_call_object_associations]
|
|
39
55
|
end
|
|
40
56
|
|
|
41
|
-
# possible_objects keep the class to object relationships
|
|
42
|
-
# that the objects may cause N+1 query.
|
|
43
|
-
# e.g. { Post => ["Post:1", "Post:2"] }
|
|
44
|
-
def possible_objects
|
|
45
|
-
Thread.current[:bullet_possible_objects]
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
# impossible_objects keep the class to objects relationships
|
|
49
|
-
# that the objects may not cause N+1 query.
|
|
50
|
-
# e.g. { Post => ["Post:1", "Post:2"] }
|
|
51
|
-
# if find collection returns only one object, then the object is impossible object,
|
|
52
|
-
# impossible_objects are used to avoid treating 1+1 query to N+1 query.
|
|
53
|
-
def impossible_objects
|
|
54
|
-
Thread.current[:bullet_impossible_objects]
|
|
55
|
-
end
|
|
56
|
-
|
|
57
57
|
# inversed_objects keeps object relationships
|
|
58
58
|
# that association is inversed.
|
|
59
59
|
# e.g. { "Comment:1" => ["post"] }
|
|
@@ -8,7 +8,7 @@ module Bullet
|
|
|
8
8
|
return unless object.primary_key_value
|
|
9
9
|
|
|
10
10
|
Bullet.debug("Detector::CounterCache#add_counter_cache", "object: #{object.bullet_key}, associations: #{associations}")
|
|
11
|
-
if conditions_met?(object
|
|
11
|
+
if conditions_met?(object, associations)
|
|
12
12
|
create_notification object.class.to_s, associations
|
|
13
13
|
end
|
|
14
14
|
end
|
|
@@ -32,6 +32,18 @@ module Bullet
|
|
|
32
32
|
impossible_objects.add object.bullet_key
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
+
def conditions_met?(object, associations)
|
|
36
|
+
possible_objects.include?(object.bullet_key) && !impossible_objects.include?(object.bullet_key)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def possible_objects
|
|
40
|
+
Thread.current[:bullet_counter_possible_objects]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def impossible_objects
|
|
44
|
+
Thread.current[:bullet_counter_impossible_objects]
|
|
45
|
+
end
|
|
46
|
+
|
|
35
47
|
private
|
|
36
48
|
def create_notification(klazz, associations)
|
|
37
49
|
notify_associations = Array(associations) - Bullet.get_whitelist_associations(:counter_cache, klazz)
|
|
@@ -41,18 +53,6 @@ module Bullet
|
|
|
41
53
|
Bullet.notification_collector.add notice
|
|
42
54
|
end
|
|
43
55
|
end
|
|
44
|
-
|
|
45
|
-
def possible_objects
|
|
46
|
-
Thread.current[:bullet_counter_possible_objects]
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def impossible_objects
|
|
50
|
-
Thread.current[:bullet_counter_impossible_objects]
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def conditions_met?(bullet_key, associations)
|
|
54
|
-
possible_objects.include?(bullet_key) && !impossible_objects.include?(bullet_key)
|
|
55
|
-
end
|
|
56
56
|
end
|
|
57
57
|
end
|
|
58
58
|
end
|