bullet 5.0.0 → 5.1.1
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 +31 -0
- data/CHANGELOG.md +13 -32
- data/Gemfile.mongoid-5.0 +1 -1
- data/Gemfile.rails-3.0 +1 -0
- data/Gemfile.rails-3.1 +1 -0
- data/Gemfile.rails-3.2 +1 -0
- data/Gemfile.rails-4.0 +1 -0
- data/Gemfile.rails-4.1 +1 -0
- data/Gemfile.rails-4.2 +1 -0
- data/Hacking.md +1 -0
- data/README.md +4 -2
- data/bullet.gemspec +1 -1
- data/lib/bullet/active_record3.rb +34 -4
- data/lib/bullet/active_record3x.rb +34 -4
- data/lib/bullet/active_record4.rb +24 -4
- data/lib/bullet/active_record41.rb +9 -1
- data/lib/bullet/active_record42.rb +13 -3
- data/lib/bullet/active_record5.rb +22 -12
- data/lib/bullet/detector/unused_eager_loading.rb +5 -7
- data/lib/bullet/notification/base.rb +2 -2
- data/lib/bullet/rack.rb +1 -1
- data/lib/bullet/version.rb +1 -1
- data/lib/bullet.rb +8 -3
- data/spec/bullet/detector/unused_eager_loading_spec.rb +14 -2
- data/spec/bullet/rack_spec.rb +31 -0
- data/spec/bullet_spec.rb +9 -0
- data/spec/integration/active_record3/association_spec.rb +65 -1
- data/spec/integration/active_record4/association_spec.rb +56 -13
- data/spec/integration/active_record5/association_spec.rb +56 -13
- data/spec/support/sqlite_seed.rb +1 -0
- data/test.sh +1 -0
- data/update.sh +1 -0
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0158f6af4990b365de2859cea97877e5b290ea83
|
|
4
|
+
data.tar.gz: cd8914938d74645ae75d01ee8feaf23e38f8d028
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9e92c13202832afaaf604072c06e695cfe552d5626318d6c625cebacdfdc13ecc14aeed8c64d6df483b4c05caa090ecee01e613228dae6466edbe66803e7333a
|
|
7
|
+
data.tar.gz: 7d365b32c075a00733e4c70daedcfbca042cb2334a77c6e132fc31b33e9dd23aaca8a65eaa1578ffba2f106303cf572e84e41b7fd6c7c61a239b2dbea9fcaabe
|
data/.travis.yml
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
sudo: false
|
|
2
2
|
language: ruby
|
|
3
3
|
rvm:
|
|
4
|
+
- 1.9.3
|
|
4
5
|
- 2.0
|
|
5
6
|
- 2.1
|
|
6
7
|
- 2.2
|
|
@@ -28,8 +29,38 @@ services:
|
|
|
28
29
|
- mongodb
|
|
29
30
|
matrix:
|
|
30
31
|
exclude:
|
|
32
|
+
- rvm: 1.9.3
|
|
33
|
+
gemfile: Gemfile.rails-4.0
|
|
34
|
+
- rvm: 1.9.3
|
|
35
|
+
gemfile: Gemfile.rails-4.1
|
|
36
|
+
- rvm: 1.9.3
|
|
37
|
+
gemfile: Gemfile.rails-4.2
|
|
38
|
+
- rvm: 1.9.3
|
|
39
|
+
gemfile: Gemfile.rails-5.0
|
|
40
|
+
- rvm: 1.9.3
|
|
41
|
+
gemfile: Gemfile.mongoid-2.4
|
|
42
|
+
- rvm: 1.9.3
|
|
43
|
+
gemfile: Gemfile.mongoid-2.5
|
|
44
|
+
- rvm: 1.9.3
|
|
45
|
+
gemfile: Gemfile.mongoid-2.6
|
|
46
|
+
- rvm: 1.9.3
|
|
47
|
+
gemfile: Gemfile.mongoid-2.7
|
|
48
|
+
- rvm: 1.9.3
|
|
49
|
+
gemfile: Gemfile.mongoid-2.8
|
|
50
|
+
- rvm: 1.9.3
|
|
51
|
+
gemfile: Gemfile.mongoid-3.0
|
|
52
|
+
- rvm: 1.9.3
|
|
53
|
+
gemfile: Gemfile.mongoid-3.1
|
|
54
|
+
- rvm: 1.9.3
|
|
55
|
+
gemfile: Gemfile.mongoid-4.0
|
|
56
|
+
- rvm: 1.9.3
|
|
57
|
+
gemfile: Gemfile.mongoid-5.0
|
|
58
|
+
- rvm: 2.0
|
|
59
|
+
gemfile: Gemfile.rails-3.0
|
|
31
60
|
- rvm: 2.0
|
|
32
61
|
gemfile: Gemfile.rails-5.0
|
|
62
|
+
- rvm: 2.1
|
|
63
|
+
gemfile: Gemfile.rails-3.0
|
|
33
64
|
- rvm: 2.1
|
|
34
65
|
gemfile: Gemfile.rails-5.0
|
|
35
66
|
- rvm: 2.2
|
data/CHANGELOG.md
CHANGED
|
@@ -1,55 +1,36 @@
|
|
|
1
1
|
# Next Release
|
|
2
2
|
|
|
3
|
-
## 5.
|
|
3
|
+
## 5.1.1
|
|
4
4
|
|
|
5
|
-
*
|
|
5
|
+
* Fix `has_cached_counter?` is not defined in HABTM #297
|
|
6
|
+
* Fix false alert if preloaded association has no records #260
|
|
6
7
|
|
|
7
|
-
##
|
|
8
|
+
## 5.1.0 (05/21/2016)
|
|
8
9
|
|
|
9
|
-
* Fix
|
|
10
|
+
* Fix false alert when `empty?` used with `counter_cache`
|
|
11
|
+
* Fix `alias_method_chain` deprecation for rails 5
|
|
12
|
+
* Add response handling for non-Rails Rack responses
|
|
13
|
+
* Fix false alert when querying immediately after creation
|
|
14
|
+
* Fix UnusedEagerLoading bug when multiple eager loading query include same objects
|
|
10
15
|
|
|
11
|
-
##
|
|
16
|
+
## 5.0.0 (01/06/2016)
|
|
12
17
|
|
|
18
|
+
* Support Rails 5.0.0.beta1
|
|
19
|
+
* Fix `has_many :through` infinite loop issue
|
|
13
20
|
* Support mongoid 5.0.0
|
|
14
21
|
* Do not report association queries immediately after object creation to
|
|
15
22
|
require a preload
|
|
16
23
|
* Detect `counter_cache` for `has_many :through` association
|
|
17
|
-
|
|
18
|
-
## 4.14.8
|
|
19
|
-
|
|
20
|
-
* compatible with `composite_primary_keys` gem
|
|
21
|
-
|
|
22
|
-
## 4.14.7
|
|
23
|
-
|
|
24
|
+
* Compatible with `composite_primary_keys` gem
|
|
24
25
|
* Fix AR 4.2 SingularAssociation#reader result can be nil
|
|
25
26
|
* `perform_out_of_channel_notifications` should always be triggered
|
|
26
|
-
|
|
27
|
-
## 4.14.6
|
|
28
|
-
|
|
29
27
|
* Fix false positive with `belongs_to` -> `belongs_to` for active\_record 4.2
|
|
30
28
|
* Activate active\_record hacks only when Bullet already start
|
|
31
|
-
|
|
32
|
-
## 4.14.5
|
|
33
|
-
|
|
34
29
|
* Don't execute query when running `to_sql`
|
|
35
30
|
* Send backtrace to `uniform_notifier`
|
|
36
31
|
* Fix sse response check
|
|
37
32
|
* Dynamically delegate available notifiers to UniformNotifier
|
|
38
|
-
|
|
39
|
-
## 4.14.4
|
|
40
|
-
|
|
41
|
-
* Fix false N + 1 warnings on Rails 4.2
|
|
42
|
-
|
|
43
|
-
## 4.14.3
|
|
44
|
-
|
|
45
|
-
* Fix false positive on create
|
|
46
|
-
|
|
47
|
-
## 4.14.2
|
|
48
|
-
|
|
49
33
|
* Hotfix nil object when `add_impossible_object`
|
|
50
|
-
|
|
51
|
-
## 4.14.1
|
|
52
|
-
|
|
53
34
|
* Fix `has_one` then `has_many` associations in rails 4.2
|
|
54
35
|
* Append js and dom to html body in proper position
|
|
55
36
|
|
data/Gemfile.mongoid-5.0
CHANGED
data/Gemfile.rails-3.0
CHANGED
data/Gemfile.rails-3.1
CHANGED
data/Gemfile.rails-3.2
CHANGED
data/Gemfile.rails-4.0
CHANGED
data/Gemfile.rails-4.1
CHANGED
data/Gemfile.rails-4.2
CHANGED
data/Hacking.md
CHANGED
|
@@ -23,6 +23,7 @@ Notification instances contain the message that will be displayed, and will
|
|
|
23
23
|
use a Presenter class to display their message to the user.
|
|
24
24
|
|
|
25
25
|
So the flow of a request goes like this:
|
|
26
|
+
|
|
26
27
|
1. Bullet.start_request is called, which resets all the detectors and empties
|
|
27
28
|
the notification collector
|
|
28
29
|
2. The request is handled by Rails, and the installed ActiveRecord extensions
|
data/README.md
CHANGED
|
@@ -238,7 +238,9 @@ Bullet outputs some details info, to enable debug mode, set
|
|
|
238
238
|
|
|
239
239
|
## Demo
|
|
240
240
|
|
|
241
|
-
Bullet is designed to function as you browse through your application in development. To see it in action,
|
|
241
|
+
Bullet is designed to function as you browse through your application in development. To see it in action,
|
|
242
|
+
you can visit [https://github.com/flyerhzm/bullet_test](https://github.com/flyerhzm/bullet_test) or
|
|
243
|
+
follow these steps to create, detect, and fix example query problems.
|
|
242
244
|
|
|
243
245
|
1\. Create an example application
|
|
244
246
|
|
|
@@ -458,4 +460,4 @@ Meanwhile, there's a line appended to `log/bullet.log`
|
|
|
458
460
|
Post => [:comments]
|
|
459
461
|
```
|
|
460
462
|
|
|
461
|
-
Copyright (c) 2009 -
|
|
463
|
+
Copyright (c) 2009 - 2016 Richard Huang (flyerhzm@gmail.com), released under the MIT license
|
data/bullet.gemspec
CHANGED
|
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
|
|
|
18
18
|
s.required_rubygems_version = ">= 1.3.6"
|
|
19
19
|
|
|
20
20
|
s.add_runtime_dependency "activesupport", ">= 3.0.0"
|
|
21
|
-
s.add_runtime_dependency "uniform_notifier", "~> 1.
|
|
21
|
+
s.add_runtime_dependency "uniform_notifier", "~> 1.10.0"
|
|
22
22
|
|
|
23
23
|
s.files = `git ls-files`.split("\n")
|
|
24
24
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
@@ -23,6 +23,24 @@ module Bullet
|
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
+
::ActiveRecord::Persistence.class_eval do
|
|
27
|
+
alias_method :origin_save, :save
|
|
28
|
+
def save(*args, &proc)
|
|
29
|
+
was_new_record = new_record?
|
|
30
|
+
origin_save(*args, &proc).tap do |result|
|
|
31
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(self) if result && was_new_record
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
alias_method :origin_save!, :save!
|
|
36
|
+
def save!(*args, &proc)
|
|
37
|
+
was_new_record = new_record?
|
|
38
|
+
origin_save!(*args, &proc).tap do |result|
|
|
39
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(self) if result && was_new_record
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
26
44
|
::ActiveRecord::AssociationPreload::ClassMethods.class_eval do
|
|
27
45
|
alias_method :origin_preload_associations, :preload_associations
|
|
28
46
|
# include query for one to many associations.
|
|
@@ -116,20 +134,32 @@ module Bullet
|
|
|
116
134
|
origin_last(*args)
|
|
117
135
|
end
|
|
118
136
|
|
|
137
|
+
alias_method :origin_include?, :include?
|
|
138
|
+
def include?(object)
|
|
139
|
+
if Bullet.start?
|
|
140
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
141
|
+
end
|
|
142
|
+
origin_include?(object)
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
::ActiveRecord::Associations::HasManyAssociation.class_eval do
|
|
119
147
|
alias_method :origin_empty?, :empty?
|
|
120
148
|
def empty?
|
|
121
|
-
if Bullet.start?
|
|
149
|
+
if Bullet.start? && !has_cached_counter?
|
|
122
150
|
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
123
151
|
end
|
|
124
152
|
origin_empty?
|
|
125
153
|
end
|
|
154
|
+
end
|
|
126
155
|
|
|
127
|
-
|
|
128
|
-
|
|
156
|
+
::ActiveRecord::Associations::HasAndBelongsToManyAssociation.class_eval do
|
|
157
|
+
alias_method :origin_empty?, :empty?
|
|
158
|
+
def empty?
|
|
129
159
|
if Bullet.start?
|
|
130
160
|
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
131
161
|
end
|
|
132
|
-
|
|
162
|
+
origin_empty?
|
|
133
163
|
end
|
|
134
164
|
end
|
|
135
165
|
|
|
@@ -21,6 +21,24 @@ module Bullet
|
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
+
::ActiveRecord::Persistence.class_eval do
|
|
25
|
+
alias_method :origin_save, :save
|
|
26
|
+
def save(*args, &proc)
|
|
27
|
+
was_new_record = new_record?
|
|
28
|
+
origin_save(*args, &proc).tap do |result|
|
|
29
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(self) if result && was_new_record
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
alias_method :origin_save!, :save!
|
|
34
|
+
def save!(*args, &proc)
|
|
35
|
+
was_new_record = new_record?
|
|
36
|
+
origin_save!(*args, &proc).tap do |result|
|
|
37
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(self) if result && was_new_record
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
24
42
|
::ActiveRecord::Associations::Preloader.class_eval do
|
|
25
43
|
# include query for one to many associations.
|
|
26
44
|
# keep this eager loadings.
|
|
@@ -98,20 +116,32 @@ module Bullet
|
|
|
98
116
|
origin_load_target
|
|
99
117
|
end
|
|
100
118
|
|
|
119
|
+
alias_method :origin_include?, :include?
|
|
120
|
+
def include?(object)
|
|
121
|
+
if Bullet.start?
|
|
122
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
123
|
+
end
|
|
124
|
+
origin_include?(object)
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
::ActiveRecord::Associations::HasManyAssociation.class_eval do
|
|
101
129
|
alias_method :origin_empty?, :empty?
|
|
102
130
|
def empty?
|
|
103
|
-
if Bullet.start?
|
|
131
|
+
if Bullet.start? && !has_cached_counter?(@reflection)
|
|
104
132
|
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
105
133
|
end
|
|
106
134
|
origin_empty?
|
|
107
135
|
end
|
|
136
|
+
end
|
|
108
137
|
|
|
109
|
-
|
|
110
|
-
|
|
138
|
+
::ActiveRecord::Associations::HasAndBelongsToManyAssociation.class_eval do
|
|
139
|
+
alias_method :origin_empty?, :empty?
|
|
140
|
+
def empty?
|
|
111
141
|
if Bullet.start?
|
|
112
142
|
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
113
143
|
end
|
|
114
|
-
|
|
144
|
+
origin_empty?
|
|
115
145
|
end
|
|
116
146
|
end
|
|
117
147
|
|
|
@@ -29,6 +29,14 @@ module Bullet
|
|
|
29
29
|
end
|
|
30
30
|
end
|
|
31
31
|
alias_method_chain :save, :bullet
|
|
32
|
+
|
|
33
|
+
def save_with_bullet!(*args, &proc)
|
|
34
|
+
was_new_record = new_record?
|
|
35
|
+
save_without_bullet!(*args, &proc).tap do |result|
|
|
36
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(self) if result && was_new_record
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
alias_method_chain :save!, :bullet
|
|
32
40
|
end
|
|
33
41
|
|
|
34
42
|
::ActiveRecord::Associations::Preloader.class_eval do
|
|
@@ -108,20 +116,32 @@ module Bullet
|
|
|
108
116
|
origin_load_target
|
|
109
117
|
end
|
|
110
118
|
|
|
119
|
+
alias_method :origin_include?, :include?
|
|
120
|
+
def include?(object)
|
|
121
|
+
if Bullet.start?
|
|
122
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
123
|
+
end
|
|
124
|
+
origin_include?(object)
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
::ActiveRecord::Associations::HasManyAssociation.class_eval do
|
|
111
129
|
alias_method :origin_empty?, :empty?
|
|
112
130
|
def empty?
|
|
113
|
-
if Bullet.start?
|
|
131
|
+
if Bullet.start? && !has_cached_counter?(@reflection)
|
|
114
132
|
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
115
133
|
end
|
|
116
134
|
origin_empty?
|
|
117
135
|
end
|
|
136
|
+
end
|
|
118
137
|
|
|
119
|
-
|
|
120
|
-
|
|
138
|
+
::ActiveRecord::Associations::HasAndBelongsToManyAssociation.class_eval do
|
|
139
|
+
alias_method :origin_empty?, :empty?
|
|
140
|
+
def empty?
|
|
121
141
|
if Bullet.start?
|
|
122
142
|
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
123
143
|
end
|
|
124
|
-
|
|
144
|
+
origin_empty?
|
|
125
145
|
end
|
|
126
146
|
end
|
|
127
147
|
|
|
@@ -31,6 +31,14 @@ module Bullet
|
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
alias_method_chain :save, :bullet
|
|
34
|
+
|
|
35
|
+
def save_with_bullet!(*args, &proc)
|
|
36
|
+
was_new_record = new_record?
|
|
37
|
+
save_without_bullet!(*args, &proc).tap do |result|
|
|
38
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(self) if result && was_new_record
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
alias_method_chain :save!, :bullet
|
|
34
42
|
end
|
|
35
43
|
|
|
36
44
|
::ActiveRecord::Associations::Preloader.class_eval do
|
|
@@ -113,7 +121,7 @@ module Bullet
|
|
|
113
121
|
|
|
114
122
|
alias_method :origin_empty?, :empty?
|
|
115
123
|
def empty?
|
|
116
|
-
if Bullet.start?
|
|
124
|
+
if Bullet.start? && !has_cached_counter?(@reflection)
|
|
117
125
|
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
118
126
|
end
|
|
119
127
|
origin_empty?
|
|
@@ -29,6 +29,14 @@ module Bullet
|
|
|
29
29
|
end
|
|
30
30
|
end
|
|
31
31
|
alias_method_chain :save, :bullet
|
|
32
|
+
|
|
33
|
+
def save_with_bullet!(*args, &proc)
|
|
34
|
+
was_new_record = new_record?
|
|
35
|
+
save_without_bullet!(*args, &proc).tap do |result|
|
|
36
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(self) if result && was_new_record
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
alias_method_chain :save!, :bullet
|
|
32
40
|
end
|
|
33
41
|
|
|
34
42
|
::ActiveRecord::Relation.class_eval do
|
|
@@ -127,7 +135,9 @@ module Bullet
|
|
|
127
135
|
records = origin_load_target
|
|
128
136
|
|
|
129
137
|
if Bullet.start?
|
|
130
|
-
|
|
138
|
+
if records.size > 1
|
|
139
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name) unless @inversed
|
|
140
|
+
end
|
|
131
141
|
if records.first.class.name !~ /^HABTM_/
|
|
132
142
|
if records.size > 1
|
|
133
143
|
Bullet::Detector::NPlusOneQuery.add_possible_objects(records)
|
|
@@ -143,7 +153,7 @@ module Bullet
|
|
|
143
153
|
|
|
144
154
|
alias_method :origin_empty?, :empty?
|
|
145
155
|
def empty?
|
|
146
|
-
if Bullet.start?
|
|
156
|
+
if Bullet.start? && !has_cached_counter?(@reflection)
|
|
147
157
|
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
148
158
|
end
|
|
149
159
|
origin_empty?
|
|
@@ -183,7 +193,7 @@ module Bullet
|
|
|
183
193
|
Thread.current[:bullet_collection_empty] = true
|
|
184
194
|
result = origin_many_empty?
|
|
185
195
|
Thread.current[:bullet_collection_empty] = nil
|
|
186
|
-
if Bullet.start?
|
|
196
|
+
if Bullet.start? && !has_cached_counter?(@reflection)
|
|
187
197
|
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
188
198
|
end
|
|
189
199
|
result
|
|
@@ -1,4 +1,20 @@
|
|
|
1
1
|
module Bullet
|
|
2
|
+
module SaveWithBulletSupport
|
|
3
|
+
def save(*args)
|
|
4
|
+
was_new_record = new_record?
|
|
5
|
+
super(*args).tap do |result|
|
|
6
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(self) if result && was_new_record
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def save!(*args)
|
|
11
|
+
was_new_record = new_record?
|
|
12
|
+
super(*args).tap do |result|
|
|
13
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(self) if result && was_new_record
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
2
18
|
module ActiveRecord
|
|
3
19
|
def self.enable
|
|
4
20
|
require 'active_record'
|
|
@@ -21,15 +37,7 @@ module Bullet
|
|
|
21
37
|
end
|
|
22
38
|
end
|
|
23
39
|
|
|
24
|
-
::ActiveRecord::
|
|
25
|
-
def save_with_bullet(*args, &proc)
|
|
26
|
-
was_new_record = new_record?
|
|
27
|
-
save_without_bullet(*args, &proc).tap do |result|
|
|
28
|
-
Bullet::Detector::NPlusOneQuery.add_impossible_object(self) if result && was_new_record
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
alias_method_chain :save, :bullet
|
|
32
|
-
end
|
|
40
|
+
::ActiveRecord::Base.prepend(SaveWithBulletSupport)
|
|
33
41
|
|
|
34
42
|
::ActiveRecord::Relation.class_eval do
|
|
35
43
|
alias_method :origin_to_a, :to_a
|
|
@@ -135,7 +143,9 @@ module Bullet
|
|
|
135
143
|
records = origin_load_target
|
|
136
144
|
|
|
137
145
|
if Bullet.start?
|
|
138
|
-
|
|
146
|
+
if records.size > 1
|
|
147
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name) unless @inversed
|
|
148
|
+
end
|
|
139
149
|
if records.first.class.name !~ /^HABTM_/
|
|
140
150
|
if records.size > 1
|
|
141
151
|
Bullet::Detector::NPlusOneQuery.add_possible_objects(records)
|
|
@@ -151,7 +161,7 @@ module Bullet
|
|
|
151
161
|
|
|
152
162
|
alias_method :origin_empty?, :empty?
|
|
153
163
|
def empty?
|
|
154
|
-
if Bullet.start?
|
|
164
|
+
if Bullet.start? && !@reflection.has_cached_counter?
|
|
155
165
|
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
156
166
|
end
|
|
157
167
|
origin_empty?
|
|
@@ -191,7 +201,7 @@ module Bullet
|
|
|
191
201
|
Thread.current[:bullet_collection_empty] = true
|
|
192
202
|
result = origin_many_empty?
|
|
193
203
|
Thread.current[:bullet_collection_empty] = nil
|
|
194
|
-
if Bullet.start?
|
|
204
|
+
if Bullet.start? && !@reflection.has_cached_counter?
|
|
195
205
|
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
196
206
|
end
|
|
197
207
|
result
|
|
@@ -27,27 +27,25 @@ module Bullet
|
|
|
27
27
|
Bullet.debug("Detector::UnusedEagerLoading#add_eager_loadings", "objects: #{objects.map(&:bullet_key).join(', ')}, associations: #{associations}")
|
|
28
28
|
bullet_keys = objects.map(&:bullet_key)
|
|
29
29
|
|
|
30
|
-
to_add =
|
|
31
|
-
to_merge, to_delete = [], []
|
|
30
|
+
to_add, to_merge, to_delete = [], [], []
|
|
32
31
|
eager_loadings.each do |k, v|
|
|
33
32
|
key_objects_overlap = k & bullet_keys
|
|
34
33
|
|
|
35
34
|
next if key_objects_overlap.empty?
|
|
36
35
|
|
|
36
|
+
bullet_keys = bullet_keys - k
|
|
37
37
|
if key_objects_overlap == k
|
|
38
|
-
to_add
|
|
39
|
-
break
|
|
38
|
+
to_add << [k, associations]
|
|
40
39
|
else
|
|
41
40
|
to_merge << [key_objects_overlap, ( eager_loadings[k].dup << associations )]
|
|
42
41
|
|
|
43
|
-
keys_without_objects = k -
|
|
42
|
+
keys_without_objects = k - key_objects_overlap
|
|
44
43
|
to_merge << [keys_without_objects, eager_loadings[k]]
|
|
45
44
|
to_delete << k
|
|
46
|
-
bullet_keys = bullet_keys - k
|
|
47
45
|
end
|
|
48
46
|
end
|
|
49
47
|
|
|
50
|
-
eager_loadings.add
|
|
48
|
+
to_add.each { |k, val| eager_loadings.add k, val }
|
|
51
49
|
to_merge.each { |k, val| eager_loadings.merge k, val }
|
|
52
50
|
to_delete.each { |k| eager_loadings.delete k }
|
|
53
51
|
|
|
@@ -57,11 +57,11 @@ module Bullet
|
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
def eql?(other)
|
|
60
|
-
klazz_associations_str == other.klazz_associations_str
|
|
60
|
+
self.class == other.class && klazz_associations_str == other.klazz_associations_str
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
def hash
|
|
64
|
-
klazz_associations_str.hash
|
|
64
|
+
[self.class, klazz_associations_str].hash
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
protected
|
data/lib/bullet/rack.rb
CHANGED
data/lib/bullet/version.rb
CHANGED
data/lib/bullet.rb
CHANGED
|
@@ -82,8 +82,8 @@ module Bullet
|
|
|
82
82
|
|
|
83
83
|
def add_whitelist(options)
|
|
84
84
|
reset_whitelist
|
|
85
|
-
@whitelist[options[:type]][options[:class_name]
|
|
86
|
-
@whitelist[options[:type]][options[:class_name]
|
|
85
|
+
@whitelist[options[:type]][options[:class_name]] ||= []
|
|
86
|
+
@whitelist[options[:type]][options[:class_name]] << options[:association].to_sym
|
|
87
87
|
end
|
|
88
88
|
|
|
89
89
|
def get_whitelist_associations(type, class_name)
|
|
@@ -190,17 +190,22 @@ module Bullet
|
|
|
190
190
|
end
|
|
191
191
|
|
|
192
192
|
def profile
|
|
193
|
+
return_value = nil
|
|
193
194
|
if Bullet.enable?
|
|
194
195
|
begin
|
|
195
196
|
Bullet.start_request
|
|
196
197
|
|
|
197
|
-
yield
|
|
198
|
+
return_value = yield
|
|
198
199
|
|
|
199
200
|
Bullet.perform_out_of_channel_notifications if Bullet.notification?
|
|
200
201
|
ensure
|
|
201
202
|
Bullet.end_request
|
|
202
203
|
end
|
|
204
|
+
else
|
|
205
|
+
return_value = yield
|
|
203
206
|
end
|
|
207
|
+
|
|
208
|
+
return_value
|
|
204
209
|
end
|
|
205
210
|
|
|
206
211
|
private
|
|
@@ -5,7 +5,8 @@ module Bullet
|
|
|
5
5
|
describe UnusedEagerLoading do
|
|
6
6
|
before(:all) do
|
|
7
7
|
@post = Post.first
|
|
8
|
-
@post2 = Post.
|
|
8
|
+
@post2 = Post.all[1]
|
|
9
|
+
@post3 = Post.last
|
|
9
10
|
end
|
|
10
11
|
|
|
11
12
|
context ".call_associations" do
|
|
@@ -72,7 +73,18 @@ module Bullet
|
|
|
72
73
|
UnusedEagerLoading.add_eager_loadings([@post, @post2], :association2)
|
|
73
74
|
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post.bullet_key], :association1)
|
|
74
75
|
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post.bullet_key], :association2)
|
|
75
|
-
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@
|
|
76
|
+
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post2.bullet_key], :association2)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it "should vmerge objects recursively, associations pair for existing eager_loadings" do
|
|
80
|
+
UnusedEagerLoading.add_eager_loadings([@post, @post2], :association1)
|
|
81
|
+
UnusedEagerLoading.add_eager_loadings([@post, @post3], :association1)
|
|
82
|
+
UnusedEagerLoading.add_eager_loadings([@post, @post3], :association2)
|
|
83
|
+
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post.bullet_key], :association1)
|
|
84
|
+
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post.bullet_key], :association2)
|
|
85
|
+
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post2.bullet_key], :association1)
|
|
86
|
+
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post3.bullet_key], :association1)
|
|
87
|
+
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post3.bullet_key], :association2)
|
|
76
88
|
end
|
|
77
89
|
|
|
78
90
|
it "should delete objects, associations pair for existing eager_loadings" do
|
data/spec/bullet/rack_spec.rb
CHANGED
|
@@ -93,5 +93,36 @@ module Bullet
|
|
|
93
93
|
end
|
|
94
94
|
end
|
|
95
95
|
end
|
|
96
|
+
|
|
97
|
+
describe "#response_body" do
|
|
98
|
+
let(:response) { double }
|
|
99
|
+
let(:body_string) { "<html><body>My Body</body></html>" }
|
|
100
|
+
|
|
101
|
+
context "when `response` responds to `body`" do
|
|
102
|
+
before { allow(response).to receive(:body).and_return(body) }
|
|
103
|
+
|
|
104
|
+
context "when `body` returns an Array" do
|
|
105
|
+
let(:body) { [body_string, 'random string'] }
|
|
106
|
+
it "should return the plain body string" do
|
|
107
|
+
expect(middleware.response_body(response)).to eq body_string
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
context "when `body` does not return an Array" do
|
|
112
|
+
let(:body) { body_string }
|
|
113
|
+
it "should return the plain body string" do
|
|
114
|
+
expect(middleware.response_body(response)).to eq body_string
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
context "when `response` does not respond to `body`" do
|
|
120
|
+
before { allow(response).to receive(:first).and_return(body_string) }
|
|
121
|
+
|
|
122
|
+
it "should return the plain body string" do
|
|
123
|
+
expect(middleware.response_body(response)).to eq body_string
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
96
127
|
end
|
|
97
128
|
end
|
data/spec/bullet_spec.rb
CHANGED
|
@@ -85,4 +85,13 @@ describe Bullet, focused: true do
|
|
|
85
85
|
end
|
|
86
86
|
end
|
|
87
87
|
end
|
|
88
|
+
|
|
89
|
+
describe '#add_whitelist' do
|
|
90
|
+
context "for 'special' class names" do
|
|
91
|
+
it 'is added to the whitelist successfully' do
|
|
92
|
+
Bullet.add_whitelist(:type => :n_plus_one_query, :class_name => 'Klass', :association => :department)
|
|
93
|
+
expect(Bullet.get_whitelist_associations(:n_plus_one_query, 'Klass')).to include :department
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
88
97
|
end
|
|
@@ -72,6 +72,16 @@ if !mongoid? && active_record3?
|
|
|
72
72
|
|
|
73
73
|
expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Post, :comments)
|
|
74
74
|
end
|
|
75
|
+
|
|
76
|
+
it "should not detect unused preload person => pets with empty?" do
|
|
77
|
+
Person.all.each do |person|
|
|
78
|
+
person.pets.empty?
|
|
79
|
+
end
|
|
80
|
+
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
|
81
|
+
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
|
82
|
+
|
|
83
|
+
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
|
84
|
+
end
|
|
75
85
|
end
|
|
76
86
|
|
|
77
87
|
context "category => posts => comments" do
|
|
@@ -204,7 +214,7 @@ if !mongoid? && active_record3?
|
|
|
204
214
|
context "post => comment" do
|
|
205
215
|
it "should detect unused preload with post => comments" do
|
|
206
216
|
Post.includes(:comments).each do |post|
|
|
207
|
-
post.comments.first.name
|
|
217
|
+
post.comments.first.name if post.comments.first
|
|
208
218
|
end
|
|
209
219
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
|
210
220
|
expect(Bullet::Detector::Association).not_to be_unused_preload_associations_for(Post, :comments)
|
|
@@ -443,6 +453,16 @@ if !mongoid? && active_record3?
|
|
|
443
453
|
|
|
444
454
|
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
|
445
455
|
end
|
|
456
|
+
|
|
457
|
+
it "should detect non preload student => teachers with empty?" do
|
|
458
|
+
Student.all.each do |student|
|
|
459
|
+
student.teachers.empty?
|
|
460
|
+
end
|
|
461
|
+
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
|
462
|
+
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
|
463
|
+
|
|
464
|
+
expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Student, :teachers)
|
|
465
|
+
end
|
|
446
466
|
end
|
|
447
467
|
end
|
|
448
468
|
|
|
@@ -537,6 +557,50 @@ if !mongoid? && active_record3?
|
|
|
537
557
|
end
|
|
538
558
|
end
|
|
539
559
|
|
|
560
|
+
describe Bullet::Detector::Association, "query immediately after creation" do
|
|
561
|
+
context "with save" do
|
|
562
|
+
context "document => children" do
|
|
563
|
+
it 'should not detect non preload associations' do
|
|
564
|
+
document1 = Document.new
|
|
565
|
+
document1.children.build
|
|
566
|
+
document1.save
|
|
567
|
+
|
|
568
|
+
document2 = Document.new(parent: document1)
|
|
569
|
+
document2.save
|
|
570
|
+
document2.parent
|
|
571
|
+
|
|
572
|
+
document1.children.each.first
|
|
573
|
+
|
|
574
|
+
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
|
575
|
+
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
|
576
|
+
|
|
577
|
+
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
|
578
|
+
end
|
|
579
|
+
end
|
|
580
|
+
end
|
|
581
|
+
|
|
582
|
+
context "with save!" do
|
|
583
|
+
context "document => children" do
|
|
584
|
+
it 'should not detect non preload associations' do
|
|
585
|
+
document1 = Document.new
|
|
586
|
+
document1.children.build
|
|
587
|
+
document1.save!
|
|
588
|
+
|
|
589
|
+
document2 = Document.new(parent: document1)
|
|
590
|
+
document2.save!
|
|
591
|
+
document2.parent
|
|
592
|
+
|
|
593
|
+
document1.children.each.first
|
|
594
|
+
|
|
595
|
+
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
|
596
|
+
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
|
597
|
+
|
|
598
|
+
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
|
599
|
+
end
|
|
600
|
+
end
|
|
601
|
+
end
|
|
602
|
+
end
|
|
603
|
+
|
|
540
604
|
describe Bullet::Detector::Association, "STI" do
|
|
541
605
|
context "page => author" do
|
|
542
606
|
it "should detect non preload associations" do
|
|
@@ -72,6 +72,16 @@ if !mongoid? && active_record4?
|
|
|
72
72
|
|
|
73
73
|
expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Post, :comments)
|
|
74
74
|
end
|
|
75
|
+
|
|
76
|
+
it "should not detect unused preload person => pets with empty?" do
|
|
77
|
+
Person.all.each do |person|
|
|
78
|
+
person.pets.empty?
|
|
79
|
+
end
|
|
80
|
+
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
|
81
|
+
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
|
82
|
+
|
|
83
|
+
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
|
84
|
+
end
|
|
75
85
|
end
|
|
76
86
|
|
|
77
87
|
context "category => posts => comments" do
|
|
@@ -204,7 +214,7 @@ if !mongoid? && active_record4?
|
|
|
204
214
|
context "post => comment" do
|
|
205
215
|
it "should detect unused preload with post => comments" do
|
|
206
216
|
Post.includes(:comments).each do |post|
|
|
207
|
-
post.comments.first.name
|
|
217
|
+
post.comments.first.name if post.comments.first
|
|
208
218
|
end
|
|
209
219
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
|
210
220
|
expect(Bullet::Detector::Association).not_to be_unused_preload_associations_for(Post, :comments)
|
|
@@ -455,6 +465,16 @@ if !mongoid? && active_record4?
|
|
|
455
465
|
|
|
456
466
|
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
|
457
467
|
end
|
|
468
|
+
|
|
469
|
+
it "should detect non preload student => teachers with empty?" do
|
|
470
|
+
Student.all.each do |student|
|
|
471
|
+
student.teachers.empty?
|
|
472
|
+
end
|
|
473
|
+
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
|
474
|
+
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
|
475
|
+
|
|
476
|
+
expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Student, :teachers)
|
|
477
|
+
end
|
|
458
478
|
end
|
|
459
479
|
end
|
|
460
480
|
|
|
@@ -561,22 +581,45 @@ if !mongoid? && active_record4?
|
|
|
561
581
|
end
|
|
562
582
|
|
|
563
583
|
describe Bullet::Detector::Association, "query immediately after creation" do
|
|
564
|
-
context "
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
584
|
+
context "with save" do
|
|
585
|
+
context "document => children" do
|
|
586
|
+
it 'should not detect non preload associations' do
|
|
587
|
+
document1 = Document.new
|
|
588
|
+
document1.children.build
|
|
589
|
+
document1.save
|
|
569
590
|
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
591
|
+
document2 = Document.new(parent: document1)
|
|
592
|
+
document2.save
|
|
593
|
+
document2.parent
|
|
573
594
|
|
|
574
|
-
|
|
595
|
+
document1.children.each.first
|
|
575
596
|
|
|
576
|
-
|
|
577
|
-
|
|
597
|
+
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
|
598
|
+
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
|
578
599
|
|
|
579
|
-
|
|
600
|
+
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
|
601
|
+
end
|
|
602
|
+
end
|
|
603
|
+
end
|
|
604
|
+
|
|
605
|
+
context "with save!" do
|
|
606
|
+
context "document => children" do
|
|
607
|
+
it 'should not detect non preload associations' do
|
|
608
|
+
document1 = Document.new
|
|
609
|
+
document1.children.build
|
|
610
|
+
document1.save!
|
|
611
|
+
|
|
612
|
+
document2 = Document.new(parent: document1)
|
|
613
|
+
document2.save!
|
|
614
|
+
document2.parent
|
|
615
|
+
|
|
616
|
+
document1.children.each.first
|
|
617
|
+
|
|
618
|
+
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
|
619
|
+
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
|
620
|
+
|
|
621
|
+
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
|
622
|
+
end
|
|
580
623
|
end
|
|
581
624
|
end
|
|
582
625
|
end
|
|
@@ -72,6 +72,16 @@ if !mongoid? && active_record5?
|
|
|
72
72
|
|
|
73
73
|
expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Post, :comments)
|
|
74
74
|
end
|
|
75
|
+
|
|
76
|
+
it "should not detect unused preload person => pets with empty?" do
|
|
77
|
+
Person.all.each do |person|
|
|
78
|
+
person.pets.empty?
|
|
79
|
+
end
|
|
80
|
+
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
|
81
|
+
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
|
82
|
+
|
|
83
|
+
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
|
84
|
+
end
|
|
75
85
|
end
|
|
76
86
|
|
|
77
87
|
context "category => posts => comments" do
|
|
@@ -204,7 +214,7 @@ if !mongoid? && active_record5?
|
|
|
204
214
|
context "post => comment" do
|
|
205
215
|
it "should detect unused preload with post => comments" do
|
|
206
216
|
Post.includes(:comments).each do |post|
|
|
207
|
-
post.comments.first.name
|
|
217
|
+
post.comments.first.name if post.comments.first
|
|
208
218
|
end
|
|
209
219
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
|
210
220
|
expect(Bullet::Detector::Association).not_to be_unused_preload_associations_for(Post, :comments)
|
|
@@ -455,6 +465,16 @@ if !mongoid? && active_record5?
|
|
|
455
465
|
|
|
456
466
|
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
|
457
467
|
end
|
|
468
|
+
|
|
469
|
+
it "should detect non preload student => teachers with empty?" do
|
|
470
|
+
Student.all.each do |student|
|
|
471
|
+
student.teachers.empty?
|
|
472
|
+
end
|
|
473
|
+
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
|
474
|
+
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
|
475
|
+
|
|
476
|
+
expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Student, :teachers)
|
|
477
|
+
end
|
|
458
478
|
end
|
|
459
479
|
end
|
|
460
480
|
|
|
@@ -561,22 +581,45 @@ if !mongoid? && active_record5?
|
|
|
561
581
|
end
|
|
562
582
|
|
|
563
583
|
describe Bullet::Detector::Association, "query immediately after creation" do
|
|
564
|
-
context "
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
584
|
+
context "with save" do
|
|
585
|
+
context "document => children" do
|
|
586
|
+
it 'should not detect non preload associations' do
|
|
587
|
+
document1 = Document.new
|
|
588
|
+
document1.children.build
|
|
589
|
+
document1.save
|
|
569
590
|
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
591
|
+
document2 = Document.new(parent: document1)
|
|
592
|
+
document2.save
|
|
593
|
+
document2.parent
|
|
573
594
|
|
|
574
|
-
|
|
595
|
+
document1.children.each.first
|
|
575
596
|
|
|
576
|
-
|
|
577
|
-
|
|
597
|
+
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
|
598
|
+
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
|
578
599
|
|
|
579
|
-
|
|
600
|
+
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
|
601
|
+
end
|
|
602
|
+
end
|
|
603
|
+
end
|
|
604
|
+
|
|
605
|
+
context "with save!" do
|
|
606
|
+
context "document => children" do
|
|
607
|
+
it 'should not detect non preload associations' do
|
|
608
|
+
document1 = Document.new
|
|
609
|
+
document1.children.build
|
|
610
|
+
document1.save!
|
|
611
|
+
|
|
612
|
+
document2 = Document.new(parent: document1)
|
|
613
|
+
document2.save!
|
|
614
|
+
document2.parent
|
|
615
|
+
|
|
616
|
+
document1.children.each.first
|
|
617
|
+
|
|
618
|
+
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
|
619
|
+
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
|
620
|
+
|
|
621
|
+
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
|
622
|
+
end
|
|
580
623
|
end
|
|
581
624
|
end
|
|
582
625
|
end
|
data/spec/support/sqlite_seed.rb
CHANGED
|
@@ -16,6 +16,7 @@ module Support
|
|
|
16
16
|
post1 = category1.posts.create(:name => 'first', :writer => writer1)
|
|
17
17
|
post1a = category1.posts.create(:name => 'like first', :writer => writer2, active: false)
|
|
18
18
|
post2 = category2.posts.create(:name => 'second', :writer => writer2)
|
|
19
|
+
post3 = category2.posts.create(:name => 'third', :writer => writer2)
|
|
19
20
|
|
|
20
21
|
comment1 = post1.comments.create(:name => 'first', :author => writer1)
|
|
21
22
|
comment2 = post1.comments.create(:name => 'first2', :author => writer1)
|
data/test.sh
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#bundle update rails && bundle exec rspec spec
|
|
2
2
|
#BUNDLE_GEMFILE=Gemfile.mongoid bundle update mongoid && BUNDLE_GEMFILE=Gemfile.mongoid bundle exec rspec spec
|
|
3
|
+
BUNDLE_GEMFILE=Gemfile.rails-5.0 bundle && BUNDLE_GEMFILE=Gemfile.rails-5.0 bundle exec rspec spec
|
|
3
4
|
BUNDLE_GEMFILE=Gemfile.rails-4.2 bundle && BUNDLE_GEMFILE=Gemfile.rails-4.2 bundle exec rspec spec
|
|
4
5
|
BUNDLE_GEMFILE=Gemfile.rails-4.1 bundle && BUNDLE_GEMFILE=Gemfile.rails-4.1 bundle exec rspec spec
|
|
5
6
|
BUNDLE_GEMFILE=Gemfile.rails-4.0 bundle && BUNDLE_GEMFILE=Gemfile.rails-4.0 bundle exec rspec spec
|
data/update.sh
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: bullet
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.
|
|
4
|
+
version: 5.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Richard Huang
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2016-
|
|
11
|
+
date: 2016-06-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -30,14 +30,14 @@ dependencies:
|
|
|
30
30
|
requirements:
|
|
31
31
|
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: 1.
|
|
33
|
+
version: 1.10.0
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: 1.
|
|
40
|
+
version: 1.10.0
|
|
41
41
|
description: help to kill N+1 queries and unused eager loading.
|
|
42
42
|
email:
|
|
43
43
|
- flyerhzm@gmail.com
|