bullet 2.0.0.beta.2 → 2.0.0.beta.3
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.
- data/.rspec +1 -0
- data/Hacking.textile +100 -0
- data/README.textile +36 -5
- data/README_for_rails2.textile +17 -0
- data/Rakefile +33 -16
- data/VERSION +1 -1
- data/autotest/discover.rb +1 -0
- data/bullet.gemspec +32 -9
- data/lib/bullet.rb +69 -38
- data/lib/bullet/action_controller2.rb +4 -4
- data/lib/bullet/active_record2.rb +16 -16
- data/lib/bullet/active_record3.rb +16 -25
- data/lib/bullet/detector.rb +9 -0
- data/lib/bullet/detector/association.rb +135 -0
- data/lib/bullet/detector/base.rb +19 -0
- data/lib/bullet/detector/counter.rb +43 -0
- data/lib/bullet/detector/n_plus_one_query.rb +39 -0
- data/lib/bullet/detector/unused_eager_association.rb +39 -0
- data/lib/bullet/notification.rb +4 -79
- data/lib/bullet/notification/base.rb +59 -0
- data/lib/bullet/notification/counter_cache.rb +13 -0
- data/lib/bullet/notification/n_plus_one_query.rb +32 -0
- data/lib/bullet/notification/unused_eager_loading.rb +14 -0
- data/lib/bullet/notification_collector.rb +25 -0
- data/lib/bullet/presenter.rb +13 -0
- data/lib/bullet/presenter/base.rb +9 -0
- data/lib/bullet/presenter/bullet_logger.rb +28 -0
- data/lib/bullet/presenter/growl.rb +40 -0
- data/lib/bullet/presenter/javascript_alert.rb +15 -0
- data/lib/bullet/presenter/javascript_console.rb +28 -0
- data/lib/bullet/presenter/javascript_helpers.rb +13 -0
- data/lib/bullet/presenter/rails_logger.rb +15 -0
- data/lib/bullet/presenter/xmpp.rb +56 -0
- data/lib/bullet/rack.rb +42 -0
- data/lib/bullet/registry.rb +7 -0
- data/lib/bullet/registry/association.rb +16 -0
- data/lib/bullet/registry/base.rb +39 -0
- data/lib/bullet/registry/object.rb +15 -0
- data/spec/bullet/association_for_chris_spec.rb +6 -6
- data/spec/bullet/association_for_peschkaj_spec.rb +6 -6
- data/spec/bullet/association_spec.rb +118 -262
- data/spec/bullet/counter_spec.rb +10 -10
- data/spec/spec_helper.rb +51 -17
- metadata +32 -9
- data/lib/bullet/association.rb +0 -294
- data/lib/bullet/counter.rb +0 -101
- data/lib/bullet/logger.rb +0 -9
- data/lib/bulletware.rb +0 -42
- data/spec/spec.opts +0 -3
data/spec/bullet/counter_spec.rb
CHANGED
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/../spec_helper'
|
|
2
2
|
|
3
3
|
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
|
4
4
|
|
5
|
-
describe Bullet::Counter do
|
5
|
+
describe Bullet::Detector::Counter do
|
6
6
|
def setup_db
|
7
7
|
ActiveRecord::Schema.define(:version => 1) do
|
8
8
|
create_table :countries do |t|
|
@@ -47,34 +47,34 @@ describe Bullet::Counter do
|
|
47
47
|
end
|
48
48
|
|
49
49
|
before(:each) do
|
50
|
-
Bullet
|
50
|
+
Bullet.start_request
|
51
51
|
end
|
52
52
|
|
53
53
|
after(:each) do
|
54
|
-
Bullet
|
54
|
+
Bullet.end_request
|
55
55
|
end
|
56
56
|
|
57
57
|
it "should need counter cache with all cities" do
|
58
58
|
Country.all.each do |country|
|
59
59
|
country.cities.size
|
60
60
|
end
|
61
|
-
Bullet
|
61
|
+
Bullet.collected_counter_cache_notifications.should_not be_empty
|
62
62
|
end
|
63
63
|
|
64
64
|
it "should not need coounter cache with only one object" do
|
65
65
|
Country.first.cities.size
|
66
|
-
Bullet
|
66
|
+
Bullet.collected_counter_cache_notifications.should be_empty
|
67
67
|
end
|
68
68
|
|
69
69
|
it "should not need counter cache with part of cities" do
|
70
70
|
Country.all.each do |country|
|
71
71
|
country.cities.where(:name => 'first').size
|
72
72
|
end
|
73
|
-
Bullet
|
73
|
+
Bullet.collected_counter_cache_notifications.should be_empty
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
|
-
describe Bullet::Counter do
|
77
|
+
describe Bullet::Detector::Counter do
|
78
78
|
def setup_db
|
79
79
|
ActiveRecord::Schema.define(:version => 1) do
|
80
80
|
create_table :people do |t|
|
@@ -120,17 +120,17 @@ describe Bullet::Counter do
|
|
120
120
|
end
|
121
121
|
|
122
122
|
before(:each) do
|
123
|
-
Bullet
|
123
|
+
Bullet.start_request
|
124
124
|
end
|
125
125
|
|
126
126
|
after(:each) do
|
127
|
-
Bullet
|
127
|
+
Bullet.end_request
|
128
128
|
end
|
129
129
|
|
130
130
|
it "should not need counter cache" do
|
131
131
|
Person.all.each do |person|
|
132
132
|
person.pets.size
|
133
133
|
end
|
134
|
-
Bullet
|
134
|
+
Bullet.collected_counter_cache_notifications.should be_empty
|
135
135
|
end
|
136
136
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -19,26 +19,60 @@ Bullet.enable = true
|
|
19
19
|
ActiveRecord::Migration.verbose = false
|
20
20
|
|
21
21
|
module Bullet
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
22
|
+
def self.collected_notifications_of_class( notification_class )
|
23
|
+
Bullet.notification_collector.collection.select do |notification|
|
24
|
+
notification.is_a? notification_class
|
25
|
+
end
|
26
|
+
end
|
28
27
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
end
|
28
|
+
def self.collected_counter_cache_notifications
|
29
|
+
collected_notifications_of_class Bullet::Notification::CounterCache
|
30
|
+
end
|
33
31
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
32
|
+
def self.collected_n_plus_one_query_notifications
|
33
|
+
collected_notifications_of_class Bullet::Notification::NPlusOneQuery
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.collected_unused_eager_association_notifications
|
37
|
+
collected_notifications_of_class Bullet::Notification::UnusedEagerLoading
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
module Bullet
|
42
|
+
module Detector
|
43
|
+
class Association
|
44
|
+
class <<self
|
45
|
+
# returns true if all associations are preloaded
|
46
|
+
def completely_preloading_associations?
|
47
|
+
Bullet.collected_n_plus_one_query_notifications.empty?
|
48
|
+
end
|
49
|
+
|
50
|
+
def has_unused_preload_associations?
|
51
|
+
Bullet.collected_unused_eager_association_notifications.present?
|
52
|
+
end
|
53
|
+
|
54
|
+
# returns true if a given object has a specific association
|
55
|
+
def creating_object_association_for?(object, association)
|
56
|
+
object_associations[object].present? && object_associations[object].include?(association)
|
57
|
+
end
|
58
|
+
|
59
|
+
# returns true if a given class includes the specific unpreloaded association
|
60
|
+
def detecting_unpreloaded_association_for?(klass, association)
|
61
|
+
for_class_and_assoc = Bullet.collected_n_plus_one_query_notifications.select do |notification|
|
62
|
+
notification.base_class == klass and
|
63
|
+
notification.associations.include?( association )
|
64
|
+
end
|
65
|
+
for_class_and_assoc.present?
|
66
|
+
end
|
38
67
|
|
39
|
-
|
40
|
-
|
41
|
-
|
68
|
+
# returns true if the given class includes the specific unused preloaded association
|
69
|
+
def unused_preload_associations_for?(klazz, association)
|
70
|
+
for_class_and_assoc = Bullet.collected_unused_eager_association_notifications.select do |notification|
|
71
|
+
notification.base_class == klass and
|
72
|
+
notification.associations.include?( association )
|
73
|
+
end
|
74
|
+
for_class_and_assoc.present?
|
75
|
+
end
|
42
76
|
end
|
43
77
|
end
|
44
78
|
end
|
metadata
CHANGED
@@ -7,8 +7,8 @@ version: !ruby/object:Gem::Version
|
|
7
7
|
- 0
|
8
8
|
- 0
|
9
9
|
- beta
|
10
|
-
-
|
11
|
-
version: 2.0.0.beta.
|
10
|
+
- 3
|
11
|
+
version: 2.0.0.beta.3
|
12
12
|
platform: ruby
|
13
13
|
authors:
|
14
14
|
- Richard Huang
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2010-
|
19
|
+
date: 2010-07-14 00:00:00 +08:00
|
20
20
|
default_executable:
|
21
21
|
dependencies: []
|
22
22
|
|
@@ -30,27 +30,50 @@ extra_rdoc_files:
|
|
30
30
|
- README.textile
|
31
31
|
- README_for_rails2.textile
|
32
32
|
files:
|
33
|
+
- .rspec
|
34
|
+
- Hacking.textile
|
33
35
|
- MIT-LICENSE
|
34
36
|
- README.textile
|
35
37
|
- README_for_rails2.textile
|
36
38
|
- Rakefile
|
37
39
|
- VERSION
|
40
|
+
- autotest/discover.rb
|
38
41
|
- bullet.gemspec
|
39
42
|
- lib/bullet.rb
|
40
43
|
- lib/bullet/action_controller2.rb
|
41
44
|
- lib/bullet/active_record2.rb
|
42
45
|
- lib/bullet/active_record3.rb
|
43
|
-
- lib/bullet/
|
44
|
-
- lib/bullet/
|
45
|
-
- lib/bullet/
|
46
|
+
- lib/bullet/detector.rb
|
47
|
+
- lib/bullet/detector/association.rb
|
48
|
+
- lib/bullet/detector/base.rb
|
49
|
+
- lib/bullet/detector/counter.rb
|
50
|
+
- lib/bullet/detector/n_plus_one_query.rb
|
51
|
+
- lib/bullet/detector/unused_eager_association.rb
|
46
52
|
- lib/bullet/notification.rb
|
47
|
-
- lib/
|
53
|
+
- lib/bullet/notification/base.rb
|
54
|
+
- lib/bullet/notification/counter_cache.rb
|
55
|
+
- lib/bullet/notification/n_plus_one_query.rb
|
56
|
+
- lib/bullet/notification/unused_eager_loading.rb
|
57
|
+
- lib/bullet/notification_collector.rb
|
58
|
+
- lib/bullet/presenter.rb
|
59
|
+
- lib/bullet/presenter/base.rb
|
60
|
+
- lib/bullet/presenter/bullet_logger.rb
|
61
|
+
- lib/bullet/presenter/growl.rb
|
62
|
+
- lib/bullet/presenter/javascript_alert.rb
|
63
|
+
- lib/bullet/presenter/javascript_console.rb
|
64
|
+
- lib/bullet/presenter/javascript_helpers.rb
|
65
|
+
- lib/bullet/presenter/rails_logger.rb
|
66
|
+
- lib/bullet/presenter/xmpp.rb
|
67
|
+
- lib/bullet/rack.rb
|
68
|
+
- lib/bullet/registry.rb
|
69
|
+
- lib/bullet/registry/association.rb
|
70
|
+
- lib/bullet/registry/base.rb
|
71
|
+
- lib/bullet/registry/object.rb
|
48
72
|
- rails/init.rb
|
49
73
|
- spec/bullet/association_for_chris_spec.rb
|
50
74
|
- spec/bullet/association_for_peschkaj_spec.rb
|
51
75
|
- spec/bullet/association_spec.rb
|
52
76
|
- spec/bullet/counter_spec.rb
|
53
|
-
- spec/spec.opts
|
54
77
|
- spec/spec_helper.rb
|
55
78
|
- tasks/bullet_tasks.rake
|
56
79
|
has_rdoc: true
|
@@ -84,7 +107,7 @@ rubyforge_project:
|
|
84
107
|
rubygems_version: 1.3.6
|
85
108
|
signing_key:
|
86
109
|
specification_version: 3
|
87
|
-
summary: A plugin to kill N+1 queries and unused eager loading
|
110
|
+
summary: A rails plugin to kill N+1 queries and unused eager loading
|
88
111
|
test_files:
|
89
112
|
- spec/spec_helper.rb
|
90
113
|
- spec/bullet/counter_spec.rb
|
data/lib/bullet/association.rb
DELETED
@@ -1,294 +0,0 @@
|
|
1
|
-
module Bullet
|
2
|
-
class Association
|
3
|
-
class <<self
|
4
|
-
include Bullet::Notification
|
5
|
-
|
6
|
-
def start_request
|
7
|
-
@@checked = false
|
8
|
-
end
|
9
|
-
|
10
|
-
def end_request
|
11
|
-
clear
|
12
|
-
end
|
13
|
-
|
14
|
-
def clear
|
15
|
-
@@object_associations = nil
|
16
|
-
@@unpreload_associations = nil
|
17
|
-
@@unused_preload_associations = nil
|
18
|
-
@@callers = nil
|
19
|
-
@@possible_objects = nil
|
20
|
-
@@impossible_objects = nil
|
21
|
-
@@call_object_associations = nil
|
22
|
-
@@eager_loadings = nil
|
23
|
-
end
|
24
|
-
|
25
|
-
def notification?
|
26
|
-
check_unused_preload_associations unless @@checked
|
27
|
-
has_unpreload_associations? or has_unused_preload_associations?
|
28
|
-
end
|
29
|
-
|
30
|
-
def add_unpreload_associations(klazz, associations)
|
31
|
-
unpreload_associations[klazz] ||= []
|
32
|
-
unpreload_associations[klazz] << associations
|
33
|
-
unique(unpreload_associations[klazz])
|
34
|
-
end
|
35
|
-
|
36
|
-
def add_unused_preload_associations(klazz, associations)
|
37
|
-
unused_preload_associations[klazz] ||= []
|
38
|
-
unused_preload_associations[klazz] << associations
|
39
|
-
unique(unused_preload_associations[klazz])
|
40
|
-
end
|
41
|
-
|
42
|
-
def add_object_associations(object, associations)
|
43
|
-
object_associations[object] ||= []
|
44
|
-
object_associations[object] << associations
|
45
|
-
unique(object_associations[object])
|
46
|
-
end
|
47
|
-
|
48
|
-
def add_call_object_associations(object, associations)
|
49
|
-
call_object_associations[object] ||= []
|
50
|
-
call_object_associations[object] << associations
|
51
|
-
unique(call_object_associations[object])
|
52
|
-
end
|
53
|
-
|
54
|
-
def add_possible_objects(objects)
|
55
|
-
klazz = objects.is_a?(Array) ? objects.first.class : objects.class
|
56
|
-
possible_objects[klazz] ||= []
|
57
|
-
possible_objects[klazz] << objects
|
58
|
-
unique(possible_objects[klazz])
|
59
|
-
end
|
60
|
-
|
61
|
-
def add_impossible_object(object)
|
62
|
-
klazz = object.class
|
63
|
-
impossible_objects[klazz] ||= []
|
64
|
-
impossible_objects[klazz] << object
|
65
|
-
impossible_objects[klazz].uniq!
|
66
|
-
end
|
67
|
-
|
68
|
-
def add_eager_loadings(objects, associations)
|
69
|
-
objects = Array(objects)
|
70
|
-
eager_loadings[objects] ||= []
|
71
|
-
eager_loadings.each do |k, v|
|
72
|
-
unless (k & objects).empty?
|
73
|
-
if (k & objects) == k
|
74
|
-
eager_loadings[k] << associations
|
75
|
-
unique(eager_loadings[k])
|
76
|
-
break
|
77
|
-
else
|
78
|
-
eager_loadings.merge!({(k & objects) => (eager_loadings[k].dup << associations)})
|
79
|
-
unique(eager_loadings[(k & objects)])
|
80
|
-
eager_loadings.merge!({(k - objects) => eager_loadings[k]}) unless (k - objects).empty?
|
81
|
-
unique(eager_loadings[(k - objects)])
|
82
|
-
eager_loadings.delete(k)
|
83
|
-
objects = objects - k
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
unless objects.empty?
|
88
|
-
eager_loadings[objects] << associations
|
89
|
-
unique(eager_loadings[objects])
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
# executed when object.assocations is called.
|
94
|
-
# first, it keeps this method call for object.association.
|
95
|
-
# then, it checks if this associations call is unpreload.
|
96
|
-
# if it is, keeps this unpreload associations and caller.
|
97
|
-
def call_association(object, associations)
|
98
|
-
add_call_object_associations(object, associations)
|
99
|
-
if unpreload_associations?(object, associations)
|
100
|
-
add_unpreload_associations(object.class, associations)
|
101
|
-
caller_in_project
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
# check if there are unused preload associations.
|
106
|
-
# for each object => association
|
107
|
-
# get related_objects from eager_loadings associated with object and associations
|
108
|
-
# get call_object_association from associations of call_object_associations whose object is in related_objects
|
109
|
-
# if association not in call_object_association, then the object => association - call_object_association is ununsed preload assocations
|
110
|
-
def check_unused_preload_associations
|
111
|
-
@@checked = true
|
112
|
-
object_associations.each do |object, association|
|
113
|
-
related_objects = eager_loadings.select {|key, value| key.include?(object) and value == association}.collect(&:first).flatten
|
114
|
-
call_object_association = related_objects.collect { |related_object| call_object_associations[related_object] }.compact.flatten.uniq
|
115
|
-
diff_object_association = (association - call_object_association).reject {|a| a.is_a? Hash}
|
116
|
-
add_unused_preload_associations(object.class, diff_object_association) unless diff_object_association.empty?
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
def has_unused_preload_associations?
|
121
|
-
!unused_preload_associations.empty?
|
122
|
-
end
|
123
|
-
|
124
|
-
def has_unpreload_associations?
|
125
|
-
!unpreload_associations.empty?
|
126
|
-
end
|
127
|
-
|
128
|
-
private
|
129
|
-
# decide whether the object.associations is unpreloaded or not.
|
130
|
-
def unpreload_associations?(object, associations)
|
131
|
-
possible?(object) and !impossible?(object) and !association?(object, associations)
|
132
|
-
end
|
133
|
-
|
134
|
-
def possible?(object)
|
135
|
-
klazz = object.class
|
136
|
-
possible_objects[klazz] and possible_objects[klazz].include?(object)
|
137
|
-
end
|
138
|
-
|
139
|
-
def impossible?(object)
|
140
|
-
klazz = object.class
|
141
|
-
impossible_objects[klazz] and impossible_objects[klazz].include?(object)
|
142
|
-
end
|
143
|
-
|
144
|
-
# check if object => associations already exists in object_associations.
|
145
|
-
def association?(object, associations)
|
146
|
-
object_associations.each do |key, value|
|
147
|
-
if key == object
|
148
|
-
value.each do |v|
|
149
|
-
result = v.is_a?(Hash) ? v.has_key?(associations) : v == associations
|
150
|
-
return true if result
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
|
-
return false
|
155
|
-
end
|
156
|
-
|
157
|
-
def notification_response
|
158
|
-
response = []
|
159
|
-
if has_unused_preload_associations?
|
160
|
-
response << unused_preload_messages.join("\n")
|
161
|
-
end
|
162
|
-
if has_unpreload_associations?
|
163
|
-
response << unpreload_messages.join("\n")
|
164
|
-
end
|
165
|
-
response
|
166
|
-
end
|
167
|
-
|
168
|
-
def console_title
|
169
|
-
title = []
|
170
|
-
title << unused_preload_messages.first.first unless unused_preload_messages.empty?
|
171
|
-
title << unpreload_messages.first.first unless unpreload_messages.empty?
|
172
|
-
title
|
173
|
-
end
|
174
|
-
|
175
|
-
def log_messages(path = nil)
|
176
|
-
messages = []
|
177
|
-
messages << unused_preload_messages(path)
|
178
|
-
messages << unpreload_messages(path)
|
179
|
-
messages << call_stack_messages
|
180
|
-
messages
|
181
|
-
end
|
182
|
-
|
183
|
-
def unused_preload_messages(path = nil)
|
184
|
-
messages = []
|
185
|
-
unused_preload_associations.each do |klazz, associations|
|
186
|
-
messages << [
|
187
|
-
"Unused Eager Loading #{path ? "in #{path}" : 'detected'}",
|
188
|
-
klazz_associations_str(klazz, associations),
|
189
|
-
" Remove from your finder: #{associations_str(associations)}"
|
190
|
-
]
|
191
|
-
end
|
192
|
-
messages
|
193
|
-
end
|
194
|
-
|
195
|
-
def unpreload_messages(path = nil)
|
196
|
-
messages = []
|
197
|
-
unpreload_associations.each do |klazz, associations|
|
198
|
-
messages << [
|
199
|
-
"N+1 Query #{path ? "in #{path}" : 'detected'}",
|
200
|
-
klazz_associations_str(klazz, associations),
|
201
|
-
" Add to your finder: #{associations_str(associations)}"
|
202
|
-
]
|
203
|
-
end
|
204
|
-
messages
|
205
|
-
end
|
206
|
-
|
207
|
-
def call_stack_messages
|
208
|
-
callers.inject([]) do |messages, c|
|
209
|
-
messages << ['N+1 Query method call stack', c.collect {|line| " #{line}"}].flatten
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
|
-
def klazz_associations_str(klazz, associations)
|
214
|
-
" #{klazz} => [#{associations.map(&:inspect).join(', ')}]"
|
215
|
-
end
|
216
|
-
|
217
|
-
def associations_str(associations)
|
218
|
-
":include => #{associations.map{|a| a.to_sym unless a.is_a? Hash}.inspect}"
|
219
|
-
end
|
220
|
-
|
221
|
-
def unique(array)
|
222
|
-
array.flatten!
|
223
|
-
array.uniq!
|
224
|
-
end
|
225
|
-
|
226
|
-
# unpreload_associations keep the class relationships
|
227
|
-
# that the associations, belongs to the class, are used but not preloaded.
|
228
|
-
# e.g. { Post => [:comments] }
|
229
|
-
# so the unpreload_associations should be preloaded by find :include.
|
230
|
-
def unpreload_associations
|
231
|
-
@@unpreload_associations ||= {}
|
232
|
-
end
|
233
|
-
|
234
|
-
# unused_preload_associations keep the class relationships
|
235
|
-
# that the associations, belongs to the class, are preloaded but not used.
|
236
|
-
# e.g. { Post => [:comments] }
|
237
|
-
# so the unused_preload_associations should be removed from find :include.
|
238
|
-
def unused_preload_associations
|
239
|
-
@@unused_preload_associations ||= {}
|
240
|
-
end
|
241
|
-
|
242
|
-
# object_associations keep the object relationships
|
243
|
-
# that the object has many associations.
|
244
|
-
# e.g. { <Post id:1> => [:comments] }
|
245
|
-
# the object_associations keep all associations that may be or may no be
|
246
|
-
# unpreload associations or unused preload associations.
|
247
|
-
def object_associations
|
248
|
-
@@object_associations ||= {}
|
249
|
-
end
|
250
|
-
|
251
|
-
# call_object_assciations keep the object relationships
|
252
|
-
# that object.associations is called.
|
253
|
-
# e.g. { <Post id:1> => [:comments] }
|
254
|
-
# they are used to detect unused preload associations.
|
255
|
-
def call_object_associations
|
256
|
-
@@call_object_associations ||= {}
|
257
|
-
end
|
258
|
-
|
259
|
-
# possible_objects keep the class to object relationships
|
260
|
-
# that the objects may cause N+1 query.
|
261
|
-
# e.g. { Post => [<Post id:1>, <Post id:2>] }
|
262
|
-
def possible_objects
|
263
|
-
@@possible_objects ||= {}
|
264
|
-
end
|
265
|
-
|
266
|
-
# impossible_objects keep the class to objects relationships
|
267
|
-
# that the objects may not cause N+1 query.
|
268
|
-
# e.g. { Post => [<Post id:1>, <Post id:2>] }
|
269
|
-
# Notice: impossible_objects are not accurate,
|
270
|
-
# if find collection returns only one object, then the object is impossible object,
|
271
|
-
# impossible_objects are used to avoid treating 1+1 query to N+1 query.
|
272
|
-
def impossible_objects
|
273
|
-
@@impossible_objects ||= {}
|
274
|
-
end
|
275
|
-
|
276
|
-
# eager_loadings keep the object relationships
|
277
|
-
# that the associations are preloaded by find :include.
|
278
|
-
# e.g. { [<Post id:1>, <Post id:2>] => [:comments, :user] }
|
279
|
-
def eager_loadings
|
280
|
-
@@eager_loadings ||= {}
|
281
|
-
end
|
282
|
-
|
283
|
-
def caller_in_project
|
284
|
-
vender_root ||= File.join(Rails.root, 'vendor')
|
285
|
-
callers << caller.select {|c| c =~ /#{Rails.root}/}.reject {|c| c =~ /#{vender_root}/}
|
286
|
-
callers.uniq!
|
287
|
-
end
|
288
|
-
|
289
|
-
def callers
|
290
|
-
@@callers ||= []
|
291
|
-
end
|
292
|
-
end
|
293
|
-
end
|
294
|
-
end
|