flyerhzm-bullet 1.5.8 → 1.5.9
Sign up to get free protection for your applications and to get access to all the features.
- data/README.textile +1 -0
- data/VERSION +1 -1
- data/bullet.gemspec +5 -5
- data/lib/bullet/active_record.rb +4 -3
- data/lib/bullet/association.rb +43 -5
- data/spec/bullet_association_spec.rb +337 -84
- data/spec/spec_helper.rb +35 -0
- metadata +3 -3
data/README.textile
CHANGED
@@ -18,6 +18,7 @@ h2. Thanks
|
|
18
18
|
|
19
19
|
flipsasser added Growl, console.log and Rails.log support, very awesome. And he improved README.
|
20
20
|
rainux add group style console.log.
|
21
|
+
2collegebums add some specs to generate red bar.
|
21
22
|
|
22
23
|
****************************************************************************
|
23
24
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.5.
|
1
|
+
1.5.9
|
data/bullet.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{bullet}
|
8
|
-
s.version = "1.5.
|
8
|
+
s.version = "1.5.9"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Richard Huang"]
|
12
|
-
s.date = %q{2009-09-
|
12
|
+
s.date = %q{2009-09-24}
|
13
13
|
s.description = %q{The Bullet plugin is designed to help you increase your application's performance by reducing the number of queries it makes. It will watch your queries while you develop your application and notify you when you should add eager loading (N+1 queries) or when you're using eager loading that isn't necessary.}
|
14
14
|
s.email = %q{flyerhzm@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -42,9 +42,9 @@ Gem::Specification.new do |s|
|
|
42
42
|
s.rubygems_version = %q{1.3.5}
|
43
43
|
s.summary = %q{A plugin to kill N+1 queries and unused eager loading}
|
44
44
|
s.test_files = [
|
45
|
-
"spec/
|
46
|
-
"spec/
|
47
|
-
"spec/
|
45
|
+
"spec/bullet_counter_spec.rb",
|
46
|
+
"spec/spec_helper.rb",
|
47
|
+
"spec/bullet_association_spec.rb"
|
48
48
|
]
|
49
49
|
|
50
50
|
if s.respond_to? :specification_version then
|
data/lib/bullet/active_record.rb
CHANGED
@@ -15,7 +15,7 @@ module Bullet
|
|
15
15
|
Bullet::Counter.add_possible_objects(records)
|
16
16
|
elsif records.size == 1
|
17
17
|
Bullet::Association.add_impossible_object(records.first)
|
18
|
-
Bullet::Counter.add_impossible_object(records)
|
18
|
+
Bullet::Counter.add_impossible_object(records.first)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
@@ -53,7 +53,7 @@ module Bullet
|
|
53
53
|
associations = merge_includes(scope(:find, :include), options[:include])
|
54
54
|
records.each do |record|
|
55
55
|
Bullet::Association.add_object_associations(record, associations)
|
56
|
-
Bullet::Association.
|
56
|
+
Bullet::Association.call_association(record, associations)
|
57
57
|
end
|
58
58
|
Bullet::Association.add_eager_loadings(records, associations)
|
59
59
|
records
|
@@ -73,7 +73,8 @@ module Bullet
|
|
73
73
|
# call has_one and belong_to association
|
74
74
|
alias_method :origin_load_target, :load_target
|
75
75
|
def load_target
|
76
|
-
|
76
|
+
# avoid stack level too deep
|
77
|
+
Bullet::Association.call_association(@owner, @reflection.name) unless caller.to_s.include? 'load_target'
|
77
78
|
origin_load_target
|
78
79
|
end
|
79
80
|
end
|
data/lib/bullet/association.rb
CHANGED
@@ -19,6 +19,7 @@ module Bullet
|
|
19
19
|
@@impossible_objects = nil
|
20
20
|
@@call_object_associations = nil
|
21
21
|
@@eager_loadings = nil
|
22
|
+
@@klazz_associations = nil
|
22
23
|
end
|
23
24
|
|
24
25
|
def notification?
|
@@ -73,8 +74,26 @@ module Bullet
|
|
73
74
|
def add_eager_loadings(objects, associations)
|
74
75
|
objects = Array(objects)
|
75
76
|
eager_loadings[objects] ||= []
|
76
|
-
eager_loadings
|
77
|
-
|
77
|
+
eager_loadings.each do |k, v|
|
78
|
+
unless (k & objects).empty?
|
79
|
+
if (k & objects) == k
|
80
|
+
eager_loadings[k] = (eager_loadings[k] + Array(associations))
|
81
|
+
unique(eager_loadings[k])
|
82
|
+
break
|
83
|
+
else
|
84
|
+
eager_loadings.merge!({(k & objects) => (eager_loadings[k] + Array(associations))})
|
85
|
+
unique(eager_loadings[(k & objects)])
|
86
|
+
eager_loadings.merge!({(k - objects) => eager_loadings[k]}) unless (k - objects).empty?
|
87
|
+
unique(eager_loadings[(k - objects)])
|
88
|
+
eager_loadings.delete(k)
|
89
|
+
objects = objects - k
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
unless objects.empty?
|
94
|
+
eager_loadings[objects] << Array(associations)
|
95
|
+
unique(eager_loadings[objects])
|
96
|
+
end
|
78
97
|
end
|
79
98
|
|
80
99
|
def define_association(klazz, associations)
|
@@ -108,10 +127,29 @@ module Bullet
|
|
108
127
|
|
109
128
|
private
|
110
129
|
def unpreload_associations?(object, associations)
|
130
|
+
possible?(object) and !impossible?(object) and !association?(object, associations)
|
131
|
+
end
|
132
|
+
|
133
|
+
def possible?(object)
|
111
134
|
klazz = object.class
|
112
|
-
|
113
|
-
|
114
|
-
|
135
|
+
possible_objects[klazz] and possible_objects[klazz].include?(object)
|
136
|
+
end
|
137
|
+
|
138
|
+
def impossible?(object)
|
139
|
+
klazz = object.class
|
140
|
+
impossible_objects[klazz] and impossible_objects[klazz].include?(object)
|
141
|
+
end
|
142
|
+
|
143
|
+
def association?(object, associations)
|
144
|
+
object_associations.each do |key, value|
|
145
|
+
if key == object
|
146
|
+
value.each do |v|
|
147
|
+
result = v.is_a?(Hash) ? v.has_key?(associations) : v == associations
|
148
|
+
return true if result
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
return false
|
115
153
|
end
|
116
154
|
|
117
155
|
def notification_response
|
@@ -3,26 +3,36 @@ require File.dirname(__FILE__) + '/spec_helper'
|
|
3
3
|
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
|
4
4
|
|
5
5
|
describe Bullet::Association, 'has_many' do
|
6
|
+
|
7
|
+
include BulletTestHelper
|
8
|
+
|
6
9
|
def setup_db
|
7
10
|
ActiveRecord::Schema.define(:version => 1) do
|
8
11
|
create_table :categories do |t|
|
9
12
|
t.column :name, :string
|
10
13
|
end
|
11
|
-
|
14
|
+
|
12
15
|
create_table :posts do |t|
|
13
16
|
t.column :name, :string
|
14
17
|
t.column :category_id, :integer
|
18
|
+
t.column :writer_id, :integer
|
15
19
|
end
|
16
20
|
|
17
21
|
create_table :comments do |t|
|
18
22
|
t.column :name, :string
|
19
23
|
t.column :post_id, :integer
|
24
|
+
t.column :author_id, :integer
|
20
25
|
end
|
21
26
|
|
22
27
|
create_table :entries do |t|
|
23
28
|
t.column :name, :string
|
24
29
|
t.column :category_id, :integer
|
25
30
|
end
|
31
|
+
|
32
|
+
create_table :base_users do |t|
|
33
|
+
t.column :name, :string
|
34
|
+
t.column :type, :string
|
35
|
+
end
|
26
36
|
end
|
27
37
|
end
|
28
38
|
|
@@ -31,7 +41,7 @@ describe Bullet::Association, 'has_many' do
|
|
31
41
|
ActiveRecord::Base.connection.drop_table(table)
|
32
42
|
end
|
33
43
|
end
|
34
|
-
|
44
|
+
|
35
45
|
class Category < ActiveRecord::Base
|
36
46
|
has_many :posts
|
37
47
|
has_many :entries
|
@@ -40,39 +50,59 @@ describe Bullet::Association, 'has_many' do
|
|
40
50
|
class Post < ActiveRecord::Base
|
41
51
|
belongs_to :category
|
42
52
|
has_many :comments
|
53
|
+
belongs_to :writer
|
54
|
+
|
43
55
|
|
44
56
|
named_scope :preload_posts, lambda { {:include => :comments} }
|
45
57
|
named_scope :in_category_name, lambda { |name|
|
46
58
|
{ :conditions => ['categories.name = ?', name], :include => :category }
|
47
59
|
}
|
48
60
|
end
|
49
|
-
|
61
|
+
|
50
62
|
class Entry < ActiveRecord::Base
|
51
63
|
belongs_to :category
|
52
64
|
end
|
53
65
|
|
54
66
|
class Comment < ActiveRecord::Base
|
55
67
|
belongs_to :post
|
68
|
+
belongs_to :author, :class_name => "BaseUser"
|
69
|
+
end
|
70
|
+
|
71
|
+
class BaseUser < ActiveRecord::Base
|
72
|
+
has_many :comments
|
73
|
+
has_many :posts
|
56
74
|
end
|
57
75
|
|
76
|
+
class Writer < BaseUser
|
77
|
+
end
|
78
|
+
|
58
79
|
before(:all) do
|
59
|
-
setup_db
|
60
|
-
|
80
|
+
silence_logger { setup_db }
|
81
|
+
|
82
|
+
writer1 = Writer.create(:name => 'first')
|
83
|
+
writer2 = Writer.create(:name => 'second')
|
84
|
+
user1 = BaseUser.create(:name => 'third')
|
85
|
+
user2 = BaseUser.create(:name => 'fourth')
|
86
|
+
|
87
|
+
|
61
88
|
category1 = Category.create(:name => 'first')
|
62
89
|
category2 = Category.create(:name => 'second')
|
63
|
-
|
64
|
-
post1 = category1.posts.create(:name => 'first')
|
65
|
-
post2 =
|
66
|
-
|
67
|
-
comment1 = post1.comments.create(:name => 'first')
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
90
|
+
|
91
|
+
post1 = category1.posts.create(:name => 'first', :writer => writer1)
|
92
|
+
post2 = category2.posts.create(:name => 'second', :writer => writer2)
|
93
|
+
|
94
|
+
comment1 = post1.comments.create(:name => 'first', :author => writer1)
|
95
|
+
comment1 = post1.comments.create(:name => 'first2', :author => writer1)
|
96
|
+
comment1 = post1.comments.create(:name => 'first3', :author => writer1)
|
97
|
+
comment2 = post1.comments.create(:name => 'second', :author => writer2)
|
98
|
+
comment3 = post2.comments.create(:name => 'third', :author => user1)
|
99
|
+
comment4 = post2.comments.create(:name => 'fourth', :author => user2)
|
100
|
+
comment4 = post2.comments.create(:name => 'fourth', :author => writer1)
|
101
|
+
|
72
102
|
entry1 = category1.entries.create(:name => 'first')
|
73
103
|
entry2 = category1.entries.create(:name => 'second')
|
74
104
|
end
|
75
|
-
|
105
|
+
|
76
106
|
after(:all) do
|
77
107
|
teardown_db
|
78
108
|
end
|
@@ -85,6 +115,92 @@ describe Bullet::Association, 'has_many' do
|
|
85
115
|
Bullet::Association.end_request
|
86
116
|
end
|
87
117
|
|
118
|
+
context "for unused cases" do
|
119
|
+
#If you have the same record created twice with different includes
|
120
|
+
# the hash value get's accumulated includes, which leads to false Unused eager loading
|
121
|
+
it "should not incorrectly mark associations as unused when multiple object instances" do
|
122
|
+
comments_with_author = Comment.all(:include => :author)
|
123
|
+
comments_with_post = Comment.all(:include => :post)
|
124
|
+
comments_with_author.each { |c| c.author.name }
|
125
|
+
comments_with_author.each { |c| c.post.name }
|
126
|
+
Bullet::Association.check_unused_preload_associations
|
127
|
+
Bullet::Association.should be_unused_preload_associations_for(Comment, :post)
|
128
|
+
Bullet::Association.should be_detecting_unpreloaded_association_for(Comment, :post)
|
129
|
+
end
|
130
|
+
|
131
|
+
# same as above with different Models being queried
|
132
|
+
it "should not incorrectly mark associations as unused when multiple object instances different Model" do
|
133
|
+
post_with_comments = Post.all(:include => :comments)
|
134
|
+
comments_with_author = Comment.all(:include => :author)
|
135
|
+
post_with_comments.each { |p| p.comments.first.author.name }
|
136
|
+
comments_with_author.each { |c| c.name }
|
137
|
+
Bullet::Association.check_unused_preload_associations
|
138
|
+
Bullet::Association.should be_unused_preload_associations_for(Comment, :author)
|
139
|
+
Bullet::Association.should be_detecting_unpreloaded_association_for(Comment, :author)
|
140
|
+
end
|
141
|
+
|
142
|
+
# this test passes right now. But is a regression test to ensure that if only a small set of returned records
|
143
|
+
# is not used that a unused preload association error is not generated
|
144
|
+
it "should not have unused when small set of returned records are discarded" do
|
145
|
+
comments_with_author = Comment.all(:include => :author)
|
146
|
+
comment_collection = comments_with_author.first(2)
|
147
|
+
comment_collection.collect { |com| com.author.name }
|
148
|
+
Bullet::Association.check_unused_preload_associations
|
149
|
+
Bullet::Association.should_not be_unused_preload_associations_for(Comment, :author)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
context "comments => posts => category" do
|
155
|
+
|
156
|
+
# this happens because the post isn't a possible object even though the writer is access through the post
|
157
|
+
# which leads to an 1+N queries
|
158
|
+
it "should detect unpreloaded writer" do
|
159
|
+
Comment.all(:include => [:author, :post],
|
160
|
+
:conditions => ["base_users.id = ?", BaseUser.first]).each do |com|
|
161
|
+
com.post.writer.name
|
162
|
+
end
|
163
|
+
Bullet::Association.should be_detecting_unpreloaded_association_for(Post, :writer)
|
164
|
+
end
|
165
|
+
|
166
|
+
# this happens because the comment doesn't break down the hash into keys
|
167
|
+
# properly creating an association from comment to post
|
168
|
+
it "should detect preload of comment => post" do
|
169
|
+
comments = Comment.all(:include => [:author, {:post => :writer}],
|
170
|
+
:conditions => ["base_users.id = ?", BaseUser.first]).each do |com|
|
171
|
+
com.post.writer.name
|
172
|
+
end
|
173
|
+
Bullet::Association.should_not be_detecting_unpreloaded_association_for(Comment, :post)
|
174
|
+
Bullet::Association.should be_completely_preloading_associations
|
175
|
+
end
|
176
|
+
|
177
|
+
# To 2collegebums: This query generate a only one sql with left outer join,
|
178
|
+
# so I think the test is not correct.
|
179
|
+
#
|
180
|
+
# this happens because it doesn't create an object association from post to writer
|
181
|
+
# by diving into the hash and creating those object associations
|
182
|
+
# it "should detect preload of post => writer" do
|
183
|
+
# comments = Comment.all(:include => [:author, {:post => :writer}],
|
184
|
+
# :conditions => ["base_users.id = ?", BaseUser.first]).each do |com|
|
185
|
+
# com.post.writer.name
|
186
|
+
# end
|
187
|
+
# Bullet::Association.should be_creating_object_association_for(comments.first, :author)
|
188
|
+
# Bullet::Association.should be_creating_object_association_for(comments.first.post, :writer)
|
189
|
+
# Bullet::Association.should_not be_detecting_unpreloaded_association_for(Post, :writer)
|
190
|
+
# Bullet::Association.should be_completely_preloading_associations
|
191
|
+
# end
|
192
|
+
|
193
|
+
# when we attempt to access category, there is an infinite overflow because load_target is hijacked leading to
|
194
|
+
# a repeating loop of calls in this test
|
195
|
+
it "should not raise a stack error from posts to category" do
|
196
|
+
lambda {
|
197
|
+
Comment.all(:include => {:post => :category}).each do |com|
|
198
|
+
com.post.category
|
199
|
+
end
|
200
|
+
}.should_not raise_error(SystemStackError)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
88
204
|
context "post => comments" do
|
89
205
|
it "should detect preload with post => comments" do
|
90
206
|
Post.find(:all, :include => :comments).each do |post|
|
@@ -92,14 +208,14 @@ describe Bullet::Association, 'has_many' do
|
|
92
208
|
end
|
93
209
|
Bullet::Association.should_not be_has_unpreload_associations
|
94
210
|
end
|
95
|
-
|
211
|
+
|
96
212
|
it "should detect no preload post => comments" do
|
97
213
|
Post.find(:all).each do |post|
|
98
214
|
post.comments.collect(&:name)
|
99
215
|
end
|
100
216
|
Bullet::Association.should be_has_unpreload_associations
|
101
217
|
end
|
102
|
-
|
218
|
+
|
103
219
|
it "should detect unused preload post => comments for post" do
|
104
220
|
Post.find(:all, :include => :comments).collect(&:name)
|
105
221
|
Bullet::Association.check_unused_preload_associations
|
@@ -111,17 +227,17 @@ describe Bullet::Association, 'has_many' do
|
|
111
227
|
Bullet::Association.check_unused_preload_associations
|
112
228
|
Bullet::Association.should_not be_has_unused_preload_associations
|
113
229
|
end
|
114
|
-
|
230
|
+
|
115
231
|
it "should detect no unused preload post => comments for comment" do
|
116
232
|
Post.find(:all).each do |post|
|
117
233
|
post.comments.collect(&:name)
|
118
234
|
end
|
119
235
|
Bullet::Association.check_unused_preload_associations
|
120
236
|
Bullet::Association.should_not be_has_unused_preload_associations
|
121
|
-
|
237
|
+
|
122
238
|
Bullet::Association.end_request
|
123
239
|
Bullet::Association.start_request
|
124
|
-
|
240
|
+
|
125
241
|
Post.find(:all).each do |post|
|
126
242
|
post.comments.collect(&:name)
|
127
243
|
end
|
@@ -129,17 +245,17 @@ describe Bullet::Association, 'has_many' do
|
|
129
245
|
Bullet::Association.should_not be_has_unused_preload_associations
|
130
246
|
end
|
131
247
|
end
|
132
|
-
|
248
|
+
|
133
249
|
context "category => posts => comments" do
|
134
250
|
it "should detect preload with category => posts => comments" do
|
135
|
-
Category.find(:all, :include => {:posts => :comments}) do |category|
|
251
|
+
Category.find(:all, :include => {:posts => :comments}).each do |category|
|
136
252
|
category.posts.each do |post|
|
137
253
|
post.comments.collect(&:name)
|
138
254
|
end
|
139
255
|
end
|
140
256
|
Bullet::Association.should_not be_has_unpreload_associations
|
141
257
|
end
|
142
|
-
|
258
|
+
|
143
259
|
it "should detect preload category => posts, but no post => comments" do
|
144
260
|
Category.find(:all, :include => :posts).each do |category|
|
145
261
|
category.posts.each do |post|
|
@@ -148,7 +264,7 @@ describe Bullet::Association, 'has_many' do
|
|
148
264
|
end
|
149
265
|
Bullet::Association.should be_has_unpreload_associations
|
150
266
|
end
|
151
|
-
|
267
|
+
|
152
268
|
it "should detect no preload category => posts => comments" do
|
153
269
|
Category.find(:all).each do |category|
|
154
270
|
category.posts.each do |post|
|
@@ -157,13 +273,13 @@ describe Bullet::Association, 'has_many' do
|
|
157
273
|
end
|
158
274
|
Bullet::Association.should be_has_unpreload_associations
|
159
275
|
end
|
160
|
-
|
276
|
+
|
161
277
|
it "should detect unused preload with category => posts => comments" do
|
162
278
|
Category.find(:all, :include => {:posts => :comments}).collect(&:name)
|
163
279
|
Bullet::Association.check_unused_preload_associations
|
164
280
|
Bullet::Association.should be_has_unused_preload_associations
|
165
281
|
end
|
166
|
-
|
282
|
+
|
167
283
|
it "should detect unused preload with post => commnets, no category => posts" do
|
168
284
|
Category.find(:all, :include => {:posts => :comments}).each do |category|
|
169
285
|
category.posts.collect(&:name)
|
@@ -171,7 +287,7 @@ describe Bullet::Association, 'has_many' do
|
|
171
287
|
Bullet::Association.check_unused_preload_associations
|
172
288
|
Bullet::Association.should be_has_unused_preload_associations
|
173
289
|
end
|
174
|
-
|
290
|
+
|
175
291
|
it "should no detect preload with category => posts => comments" do
|
176
292
|
Category.find(:all).each do |category|
|
177
293
|
category.posts.each do |post|
|
@@ -182,7 +298,7 @@ describe Bullet::Association, 'has_many' do
|
|
182
298
|
Bullet::Association.should_not be_has_unused_preload_associations
|
183
299
|
end
|
184
300
|
end
|
185
|
-
|
301
|
+
|
186
302
|
context "category => posts, category => entries" do
|
187
303
|
it "should detect preload with category => [posts, entries]" do
|
188
304
|
Category.find(:all, :include => [:posts, :entries]).each do |category|
|
@@ -207,13 +323,13 @@ describe Bullet::Association, 'has_many' do
|
|
207
323
|
end
|
208
324
|
Bullet::Association.should be_has_unpreload_associations
|
209
325
|
end
|
210
|
-
|
326
|
+
|
211
327
|
it "should detect unused with category => [posts, entries]" do
|
212
328
|
Category.find(:all, :include => [:posts, :entries]).collect(&:name)
|
213
329
|
Bullet::Association.check_unused_preload_associations
|
214
330
|
Bullet::Association.should be_has_unused_preload_associations
|
215
331
|
end
|
216
|
-
|
332
|
+
|
217
333
|
it "should detect unused preload with category => entries, but no category => posts" do
|
218
334
|
Category.find(:all, :include => [:posts, :entries]).each do |category|
|
219
335
|
category.posts.collect(&:name)
|
@@ -221,7 +337,7 @@ describe Bullet::Association, 'has_many' do
|
|
221
337
|
Bullet::Association.check_unused_preload_associations
|
222
338
|
Bullet::Association.should be_has_unused_preload_associations
|
223
339
|
end
|
224
|
-
|
340
|
+
|
225
341
|
it "should detect no unused preload" do
|
226
342
|
Category.find(:all).each do |category|
|
227
343
|
category.posts.collect(&:name)
|
@@ -247,19 +363,19 @@ describe Bullet::Association, 'has_many' do
|
|
247
363
|
end
|
248
364
|
|
249
365
|
context "named_scope for_category_name" do
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
366
|
+
it "should detect preload with post => category" do
|
367
|
+
Post.in_category_name('first').all.each do |post|
|
368
|
+
post.category.name
|
369
|
+
end
|
370
|
+
Bullet::Association.should_not be_has_unpreload_associations
|
371
|
+
end
|
372
|
+
|
373
|
+
it "should not be unused preload post => category" do
|
374
|
+
Post.in_category_name('first').all.collect(&:name)
|
375
|
+
Bullet::Association.should_not be_has_unpreload_associations
|
376
|
+
Bullet::Association.check_unused_preload_associations
|
377
|
+
Bullet::Association.should_not be_has_unused_preload_associations
|
378
|
+
end
|
263
379
|
end
|
264
380
|
|
265
381
|
context "named_scope preload_posts" do
|
@@ -302,31 +418,31 @@ describe Bullet::Association, 'has_many' do
|
|
302
418
|
end
|
303
419
|
Bullet::Association.should be_has_unpreload_associations
|
304
420
|
end
|
305
|
-
|
421
|
+
|
306
422
|
it "should no preload comment => post" do
|
307
423
|
Comment.first.post.name
|
308
424
|
Bullet::Association.should_not be_has_unpreload_associations
|
309
425
|
end
|
310
|
-
|
426
|
+
|
311
427
|
it "should no preload comments => post" do
|
312
428
|
Comment.find(:all, :include => :post).each do |comment|
|
313
429
|
comment.post.name
|
314
430
|
end
|
315
431
|
Bullet::Association.should_not be_has_unpreload_associations
|
316
432
|
end
|
317
|
-
|
433
|
+
|
318
434
|
it "should detect no unused preload comments => post" do
|
319
435
|
Comment.find(:all).collect(&:name)
|
320
436
|
Bullet::Association.check_unused_preload_associations
|
321
437
|
Bullet::Association.should_not be_has_unused_preload_associations
|
322
438
|
end
|
323
|
-
|
439
|
+
|
324
440
|
it "should detect unused preload comments => post" do
|
325
441
|
Comment.find(:all, :include => :post).collect(&:name)
|
326
442
|
Bullet::Association.check_unused_preload_associations
|
327
443
|
Bullet::Association.should be_has_unused_preload_associations
|
328
444
|
end
|
329
|
-
|
445
|
+
|
330
446
|
it "should dectect no unused preload comments => post" do
|
331
447
|
Comment.find(:all).each do |comment|
|
332
448
|
comment.post.name
|
@@ -334,7 +450,7 @@ describe Bullet::Association, 'has_many' do
|
|
334
450
|
Bullet::Association.check_unused_preload_associations
|
335
451
|
Bullet::Association.should_not be_has_unused_preload_associations
|
336
452
|
end
|
337
|
-
|
453
|
+
|
338
454
|
it "should dectect no unused preload comments => post" do
|
339
455
|
Comment.find(:all, :include => :post).each do |comment|
|
340
456
|
comment.post.name
|
@@ -346,12 +462,14 @@ describe Bullet::Association, 'has_many' do
|
|
346
462
|
end
|
347
463
|
|
348
464
|
describe Bullet::Association, 'has_and_belongs_to_many' do
|
465
|
+
|
466
|
+
include BulletTestHelper
|
349
467
|
def setup_db
|
350
468
|
ActiveRecord::Schema.define(:version => 1) do
|
351
469
|
create_table :students do |t|
|
352
470
|
t.column :name, :string
|
353
471
|
end
|
354
|
-
|
472
|
+
|
355
473
|
create_table :teachers do |t|
|
356
474
|
t.column :name, :string
|
357
475
|
end
|
@@ -378,7 +496,7 @@ describe Bullet::Association, 'has_and_belongs_to_many' do
|
|
378
496
|
end
|
379
497
|
|
380
498
|
before(:all) do
|
381
|
-
setup_db
|
499
|
+
silence_logger { setup_db }
|
382
500
|
student1 = Student.create(:name => 'first')
|
383
501
|
student2 = Student.create(:name => 'second')
|
384
502
|
teacher1 = Teacher.create(:name => 'first')
|
@@ -401,27 +519,27 @@ describe Bullet::Association, 'has_and_belongs_to_many' do
|
|
401
519
|
Bullet::Association.end_request
|
402
520
|
end
|
403
521
|
|
404
|
-
it "should detect unpreload
|
522
|
+
it "should detect unpreload associations" do
|
405
523
|
Student.find(:all).each do |student|
|
406
524
|
student.teachers.collect(&:name)
|
407
525
|
end
|
408
526
|
Bullet::Association.should be_has_unpreload_associations
|
409
527
|
end
|
410
528
|
|
411
|
-
it "should detect no unpreload
|
529
|
+
it "should detect no unpreload associations" do
|
412
530
|
Student.find(:all, :include => :teachers).each do |student|
|
413
531
|
student.teachers.collect(&:name)
|
414
532
|
end
|
415
533
|
Bullet::Association.should_not be_has_unpreload_associations
|
416
534
|
end
|
417
|
-
|
418
|
-
it "should detect unused preload
|
535
|
+
|
536
|
+
it "should detect unused preload associations" do
|
419
537
|
Student.find(:all, :include => :teachers).collect(&:name)
|
420
538
|
Bullet::Association.check_unused_preload_associations
|
421
539
|
Bullet::Association.should be_has_unused_preload_associations
|
422
540
|
end
|
423
541
|
|
424
|
-
it "should detect no unused preload
|
542
|
+
it "should detect no unused preload associations" do
|
425
543
|
Student.find(:all).collect(&:name)
|
426
544
|
Bullet::Association.check_unused_preload_associations
|
427
545
|
Bullet::Association.should_not be_has_unused_preload_associations
|
@@ -429,12 +547,15 @@ describe Bullet::Association, 'has_and_belongs_to_many' do
|
|
429
547
|
end
|
430
548
|
|
431
549
|
describe Bullet::Association, 'has_many :through' do
|
550
|
+
|
551
|
+
include BulletTestHelper
|
552
|
+
|
432
553
|
def setup_db
|
433
554
|
ActiveRecord::Schema.define(:version => 1) do
|
434
555
|
create_table :firms do |t|
|
435
556
|
t.column :name, :string
|
436
557
|
end
|
437
|
-
|
558
|
+
|
438
559
|
create_table :clients do |t|
|
439
560
|
t.column :name, :string
|
440
561
|
end
|
@@ -468,7 +589,7 @@ describe Bullet::Association, 'has_many :through' do
|
|
468
589
|
end
|
469
590
|
|
470
591
|
before(:all) do
|
471
|
-
setup_db
|
592
|
+
silence_logger { setup_db }
|
472
593
|
firm1 = Firm.create(:name => 'first')
|
473
594
|
firm2 = Firm.create(:name => 'second')
|
474
595
|
client1 = Client.create(:name => 'first')
|
@@ -491,27 +612,27 @@ describe Bullet::Association, 'has_many :through' do
|
|
491
612
|
Bullet::Association.end_request
|
492
613
|
end
|
493
614
|
|
494
|
-
it "should detect unpreload
|
615
|
+
it "should detect unpreload associations" do
|
495
616
|
Firm.find(:all).each do |firm|
|
496
617
|
firm.clients.collect(&:name)
|
497
618
|
end
|
498
619
|
Bullet::Association.should be_has_unpreload_associations
|
499
620
|
end
|
500
621
|
|
501
|
-
it "should detect no unpreload
|
622
|
+
it "should detect no unpreload associations" do
|
502
623
|
Firm.find(:all, :include => :clients).each do |firm|
|
503
624
|
firm.clients.collect(&:name)
|
504
625
|
end
|
505
626
|
Bullet::Association.should_not be_has_unpreload_associations
|
506
627
|
end
|
507
628
|
|
508
|
-
it "should detect no unused preload
|
629
|
+
it "should detect no unused preload associations" do
|
509
630
|
Firm.find(:all).collect(&:name)
|
510
631
|
Bullet::Association.check_unused_preload_associations
|
511
632
|
Bullet::Association.should_not be_has_unused_preload_associations
|
512
633
|
end
|
513
634
|
|
514
|
-
it "should detect unused preload
|
635
|
+
it "should detect unused preload associations" do
|
515
636
|
Firm.find(:all, :include => :clients).collect(&:name)
|
516
637
|
Bullet::Association.check_unused_preload_associations
|
517
638
|
Bullet::Association.should be_has_unused_preload_associations
|
@@ -519,17 +640,25 @@ describe Bullet::Association, 'has_many :through' do
|
|
519
640
|
end
|
520
641
|
|
521
642
|
describe Bullet::Association, 'has_many :as' do
|
643
|
+
|
644
|
+
include BulletTestHelper
|
645
|
+
|
522
646
|
def setup_db
|
523
647
|
ActiveRecord::Schema.define(:version => 1) do
|
524
648
|
create_table :votes do |t|
|
525
649
|
t.column :vote, :integer
|
526
650
|
t.references :voteable, :polymorphic => true
|
527
651
|
end
|
528
|
-
|
652
|
+
|
529
653
|
create_table :users do |t|
|
530
654
|
t.column :name, :string
|
531
655
|
end
|
532
656
|
|
657
|
+
create_table :pets do |t|
|
658
|
+
t.column :name, :string
|
659
|
+
t.column :user_id, :integer
|
660
|
+
end
|
661
|
+
|
533
662
|
create_table :news do |t|
|
534
663
|
t.column :name, :string
|
535
664
|
end
|
@@ -548,6 +677,11 @@ describe Bullet::Association, 'has_many :as' do
|
|
548
677
|
|
549
678
|
class User < ActiveRecord::Base
|
550
679
|
has_many :votes, :as => :voteable
|
680
|
+
has_many :pets
|
681
|
+
end
|
682
|
+
|
683
|
+
class Pet < ActiveRecord::Base
|
684
|
+
belongs_to :user
|
551
685
|
end
|
552
686
|
|
553
687
|
class News < ActiveRecord::Base
|
@@ -555,13 +689,25 @@ describe Bullet::Association, 'has_many :as' do
|
|
555
689
|
end
|
556
690
|
|
557
691
|
before(:all) do
|
558
|
-
setup_db
|
692
|
+
silence_logger { setup_db }
|
559
693
|
user1 = User.create(:name => 'first')
|
560
694
|
user2 = User.create(:name => 'second')
|
695
|
+
user3 = User.create(:name => 'third')
|
696
|
+
user4 = User.create(:name => 'fourth')
|
697
|
+
|
698
|
+
pet1 = User.create(:name => "dog")
|
699
|
+
pet2 = User.create(:name => "dog")
|
700
|
+
pet3 = User.create(:name => "cat")
|
701
|
+
pet4 = User.create(:name => "cat")
|
702
|
+
|
561
703
|
user1.votes << Vote.create(:vote => 10)
|
562
704
|
user1.votes << Vote.create(:vote => 20)
|
563
705
|
user2.votes << Vote.create(:vote => 10)
|
564
706
|
user2.votes << Vote.create(:vote => 20)
|
707
|
+
user3.votes << Vote.create(:vote => 10)
|
708
|
+
user3.votes << Vote.create(:vote => 20)
|
709
|
+
user4.votes << Vote.create(:vote => 10)
|
710
|
+
user4.votes << Vote.create(:vote => 20)
|
565
711
|
|
566
712
|
news1 = News.create(:name => 'first')
|
567
713
|
news2 = News.create(:name => 'second')
|
@@ -582,54 +728,65 @@ describe Bullet::Association, 'has_many :as' do
|
|
582
728
|
after(:each) do
|
583
729
|
Bullet::Association.end_request
|
584
730
|
end
|
731
|
+
|
732
|
+
# this happens only when a polymorphic association is included along with another table which is being referenced in the query
|
733
|
+
it "should not have unused preloaded associations with conditions" do
|
734
|
+
all_users = User.all(:include => :pets)
|
735
|
+
users_with_ten_votes = User.all(:include => :votes, :conditions => ["votes.vote = ?", 10])
|
736
|
+
users_without_ten_votes = User.all(:conditions => ["users.id not in (?)", users_with_ten_votes.collect(&:id)])
|
737
|
+
all_users.collect { |t| t.pets.collect(&:name) }
|
738
|
+
Bullet::Association.check_unused_preload_associations
|
739
|
+
Bullet::Association.should_not be_unused_preload_associations_for(User, :pets)
|
740
|
+
Bullet::Association.should_not be_unused_preload_associations_for(User, :votes)
|
741
|
+
end
|
585
742
|
|
586
|
-
it "should detect unpreload
|
743
|
+
it "should detect unpreload associations" do
|
587
744
|
User.find(:all).each do |user|
|
588
745
|
user.votes.collect(&:vote)
|
589
746
|
end
|
590
747
|
Bullet::Association.should be_has_unpreload_associations
|
591
748
|
end
|
592
749
|
|
593
|
-
it "should detect no unpreload
|
750
|
+
it "should detect no unpreload associations" do
|
594
751
|
User.find(:all, :include => :votes).each do |user|
|
595
752
|
user.votes.collect(&:vote)
|
596
753
|
end
|
597
754
|
Bullet::Association.should_not be_has_unpreload_associations
|
598
755
|
end
|
599
756
|
|
600
|
-
it "should detect unpreload
|
757
|
+
it "should detect unpreload associations with voteable" do
|
601
758
|
Vote.find(:all).each do |vote|
|
602
759
|
vote.voteable.name
|
603
760
|
end
|
604
761
|
Bullet::Association.should be_has_unpreload_associations
|
605
762
|
end
|
606
763
|
|
607
|
-
it "should detect no unpreload
|
764
|
+
it "should detect no unpreload associations with voteable" do
|
608
765
|
Vote.find(:all, :include => :voteable).each do |vote|
|
609
766
|
vote.voteable.name
|
610
767
|
end
|
611
768
|
Bullet::Association.should_not be_has_unpreload_associations
|
612
769
|
end
|
613
|
-
|
770
|
+
|
614
771
|
it "should detect no unused preload associations" do
|
615
772
|
User.find(:all).collect(&:name)
|
616
773
|
Bullet::Association.check_unused_preload_associations
|
617
774
|
Bullet::Association.should_not be_has_unused_preload_associations
|
618
775
|
end
|
619
|
-
|
776
|
+
|
620
777
|
it "should detect unused preload associations" do
|
621
778
|
User.find(:all, :include => :votes).collect(&:name)
|
622
779
|
Bullet::Association.check_unused_preload_associations
|
623
780
|
Bullet::Association.should be_has_unused_preload_associations
|
624
781
|
end
|
625
|
-
|
782
|
+
|
626
783
|
it "should detect no unused preload associations with voteable" do
|
627
784
|
Vote.find(:all).collect(&:vote)
|
628
785
|
Bullet::Association.check_unused_preload_associations
|
629
786
|
Bullet::Association.should_not be_has_unused_preload_associations
|
630
787
|
end
|
631
788
|
|
632
|
-
it "should detect unused preload
|
789
|
+
it "should detect unused preload associations with voteable" do
|
633
790
|
Vote.find(:all, :include => :voteable).collect(&:vote)
|
634
791
|
Bullet::Association.check_unused_preload_associations
|
635
792
|
Bullet::Association.should be_has_unused_preload_associations
|
@@ -637,6 +794,9 @@ describe Bullet::Association, 'has_many :as' do
|
|
637
794
|
end
|
638
795
|
|
639
796
|
describe Bullet::Association, "has_one" do
|
797
|
+
|
798
|
+
include BulletTestHelper
|
799
|
+
|
640
800
|
def setup_db
|
641
801
|
ActiveRecord::Schema.define(:version => 1) do
|
642
802
|
create_table :companies do |t|
|
@@ -665,7 +825,7 @@ describe Bullet::Association, "has_one" do
|
|
665
825
|
end
|
666
826
|
|
667
827
|
before(:all) do
|
668
|
-
setup_db
|
828
|
+
silence_logger { setup_db }
|
669
829
|
|
670
830
|
company1 = Company.create(:name => 'first')
|
671
831
|
company2 = Company.create(:name => 'second')
|
@@ -699,7 +859,7 @@ describe Bullet::Association, "has_one" do
|
|
699
859
|
end
|
700
860
|
Bullet::Association.should_not be_has_unpreload_associations
|
701
861
|
end
|
702
|
-
|
862
|
+
|
703
863
|
it "should detect no unused preload association" do
|
704
864
|
Company.find(:all).collect(&:name)
|
705
865
|
Bullet::Association.check_unused_preload_associations
|
@@ -713,13 +873,14 @@ describe Bullet::Association, "has_one" do
|
|
713
873
|
end
|
714
874
|
end
|
715
875
|
|
716
|
-
describe Bullet::Association, "call one association that in
|
876
|
+
describe Bullet::Association, "call one association that in possible objects" do
|
877
|
+
include BulletTestHelper
|
717
878
|
def setup_db
|
718
879
|
ActiveRecord::Schema.define(:version => 1) do
|
719
880
|
create_table :contacts do |t|
|
720
881
|
t.column :name, :string
|
721
882
|
end
|
722
|
-
|
883
|
+
|
723
884
|
create_table :emails do |t|
|
724
885
|
t.column :name, :string
|
725
886
|
t.column :contact_id, :integer
|
@@ -732,21 +893,21 @@ describe Bullet::Association, "call one association that in possiable objects" d
|
|
732
893
|
ActiveRecord::Base.connection.drop_table(table)
|
733
894
|
end
|
734
895
|
end
|
735
|
-
|
896
|
+
|
736
897
|
class Contact < ActiveRecord::Base
|
737
898
|
has_many :emails
|
738
899
|
end
|
739
|
-
|
900
|
+
|
740
901
|
class Email < ActiveRecord::Base
|
741
902
|
belongs_to :contact
|
742
903
|
end
|
743
|
-
|
904
|
+
|
744
905
|
before(:all) do
|
745
|
-
setup_db
|
746
|
-
|
906
|
+
silence_logger { setup_db }
|
907
|
+
|
747
908
|
contact1 = Contact.create(:name => 'first')
|
748
909
|
contact2 = Contact.create(:name => 'second')
|
749
|
-
|
910
|
+
|
750
911
|
email1 = contact1.emails.create(:name => 'first')
|
751
912
|
email2 = contact1.emails.create(:name => 'second')
|
752
913
|
email3 = contact2.emails.create(:name => 'third')
|
@@ -764,10 +925,102 @@ describe Bullet::Association, "call one association that in possiable objects" d
|
|
764
925
|
after(:each) do
|
765
926
|
Bullet::Association.end_request
|
766
927
|
end
|
767
|
-
|
928
|
+
|
768
929
|
it "should detect no unpreload association" do
|
769
930
|
Contact.find(:all)
|
770
931
|
Contact.first.emails.collect(&:name)
|
771
932
|
Bullet::Association.should_not be_has_unpreload_associations
|
772
933
|
end
|
773
934
|
end
|
935
|
+
|
936
|
+
describe Bullet::Association, "STI" do
|
937
|
+
include BulletTestHelper
|
938
|
+
def setup_db
|
939
|
+
ActiveRecord::Schema.define(:version => 1) do
|
940
|
+
create_table :documents do |t|
|
941
|
+
t.string :name
|
942
|
+
t.string :type
|
943
|
+
t.integer :parent_id
|
944
|
+
t.integer :author_id
|
945
|
+
end
|
946
|
+
|
947
|
+
create_table :authors do |t|
|
948
|
+
t.string :name
|
949
|
+
end
|
950
|
+
end
|
951
|
+
end
|
952
|
+
|
953
|
+
def teardown_db
|
954
|
+
ActiveRecord::Base.connection.tables.each do |table|
|
955
|
+
ActiveRecord::Base.connection.drop_table(table)
|
956
|
+
end
|
957
|
+
end
|
958
|
+
|
959
|
+
class Document < ActiveRecord::Base
|
960
|
+
has_many :children, :class_name => "Document", :foreign_key => 'parent_id'
|
961
|
+
belongs_to :parent, :class_name => "Document", :foreign_key => 'parent_id'
|
962
|
+
belongs_to :author
|
963
|
+
end
|
964
|
+
|
965
|
+
class Page < Document
|
966
|
+
end
|
967
|
+
|
968
|
+
class Folder < Document
|
969
|
+
end
|
970
|
+
|
971
|
+
class Author < ActiveRecord::Base
|
972
|
+
has_many :documents
|
973
|
+
end
|
974
|
+
|
975
|
+
before(:all) do
|
976
|
+
silence_logger { setup_db }
|
977
|
+
author1 = Author.create(:name => 'author1')
|
978
|
+
author2 = Author.create(:name => 'author2')
|
979
|
+
folder1 = Folder.create(:name => 'folder1', :author_id => author1.id)
|
980
|
+
folder2 = Folder.create(:name => 'folder2', :author_id => author2.id)
|
981
|
+
page1 = Page.create(:name => 'page1', :parent_id => folder1.id, :author_id => author1.id)
|
982
|
+
page2 = Page.create(:name => 'page2', :parent_id => folder1.id, :author_id => author1.id)
|
983
|
+
page3 = Page.create(:name => 'page3', :parent_id => folder2.id, :author_id => author2.id)
|
984
|
+
page4 = Page.create(:name => 'page4', :parent_id => folder2.id, :author_id => author2.id)
|
985
|
+
end
|
986
|
+
|
987
|
+
before(:each) do
|
988
|
+
Bullet::Association.start_request
|
989
|
+
end
|
990
|
+
|
991
|
+
after(:each) do
|
992
|
+
Bullet::Association.end_request
|
993
|
+
end
|
994
|
+
|
995
|
+
it "should detect unpreload associations" do
|
996
|
+
Page.find(:all).each do |page|
|
997
|
+
page.author.name
|
998
|
+
end
|
999
|
+
Bullet::Association.should be_has_unpreload_associations
|
1000
|
+
Bullet::Association.check_unused_preload_associations
|
1001
|
+
Bullet::Association.should_not be_has_unused_preload_associations
|
1002
|
+
end
|
1003
|
+
|
1004
|
+
it "should not detect unpreload associations" do
|
1005
|
+
Page.find(:all, :include => :author).each do |page|
|
1006
|
+
page.author.name
|
1007
|
+
end
|
1008
|
+
Bullet::Association.should_not be_has_unpreload_associations
|
1009
|
+
Bullet::Association.check_unused_preload_associations
|
1010
|
+
Bullet::Association.should_not be_has_unused_preload_associations
|
1011
|
+
end
|
1012
|
+
|
1013
|
+
it "should detect unused preload associations" do
|
1014
|
+
Page.find(:all, :include => :author).collect(&:name)
|
1015
|
+
Bullet::Association.should_not be_has_unpreload_associations
|
1016
|
+
Bullet::Association.check_unused_preload_associations
|
1017
|
+
Bullet::Association.should be_has_unused_preload_associations
|
1018
|
+
end
|
1019
|
+
|
1020
|
+
it "should not detect unused preload associations" do
|
1021
|
+
Page.find(:all).collect(&:name)
|
1022
|
+
Bullet::Association.should_not be_has_unpreload_associations
|
1023
|
+
Bullet::Association.check_unused_preload_associations
|
1024
|
+
Bullet::Association.should_not be_has_unused_preload_associations
|
1025
|
+
end
|
1026
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -13,3 +13,38 @@ require File.expand_path(File.join(File.dirname(__FILE__), '../lib/bullet/counte
|
|
13
13
|
require File.expand_path(File.join(File.dirname(__FILE__), '../lib/bullet'))
|
14
14
|
require File.expand_path(File.join(File.dirname(__FILE__), '../lib/bulletware'))
|
15
15
|
Bullet.enable = true
|
16
|
+
|
17
|
+
module BulletTestHelper
|
18
|
+
def silence_logger(&block)
|
19
|
+
orig_stdout = $stdout
|
20
|
+
$stdout = StringIO.new
|
21
|
+
block.call
|
22
|
+
$stdout = orig_stdout
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module Bullet
|
27
|
+
class Association
|
28
|
+
class <<self
|
29
|
+
# returns true if all associations are preloaded
|
30
|
+
def completely_preloading_associations?
|
31
|
+
!has_unpreload_associations?
|
32
|
+
end
|
33
|
+
|
34
|
+
# returns true if a given object has a specific association
|
35
|
+
def creating_object_association_for?(object, association)
|
36
|
+
object_associations[object].present? && object_associations[object].include?(association)
|
37
|
+
end
|
38
|
+
|
39
|
+
# returns true if a given class includes the specific unpreloaded association
|
40
|
+
def detecting_unpreloaded_association_for?(klazz, association)
|
41
|
+
unpreload_associations[klazz].present? && unpreload_associations[klazz].include?(association)
|
42
|
+
end
|
43
|
+
|
44
|
+
# returns true if the given class includes the specific unused preloaded association
|
45
|
+
def unused_preload_associations_for?(klazz, association)
|
46
|
+
unused_preload_associations[klazz].present? && unused_preload_associations[klazz].include?(association)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flyerhzm-bullet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.5.
|
4
|
+
version: 1.5.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Richard Huang
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-09-
|
12
|
+
date: 2009-09-24 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -69,6 +69,6 @@ signing_key:
|
|
69
69
|
specification_version: 3
|
70
70
|
summary: A plugin to kill N+1 queries and unused eager loading
|
71
71
|
test_files:
|
72
|
-
- spec/bullet_association_spec.rb
|
73
72
|
- spec/bullet_counter_spec.rb
|
74
73
|
- spec/spec_helper.rb
|
74
|
+
- spec/bullet_association_spec.rb
|