bullet 5.1.0 → 5.3.0
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 +13 -13
- data/CHANGELOG.md +15 -2
- data/Gemfile.mongoid-2.4 +0 -2
- data/Gemfile.mongoid-2.5 +0 -2
- data/Gemfile.mongoid-2.6 +0 -2
- data/Gemfile.mongoid-2.7 +0 -2
- data/Gemfile.mongoid-2.8 +0 -2
- data/Gemfile.mongoid-3.0 +0 -2
- data/Gemfile.mongoid-3.1 +0 -2
- data/Gemfile.mongoid-4.0 +0 -2
- data/Gemfile.mongoid-5.0 +0 -2
- data/Gemfile.rails-3.0 +0 -2
- data/Gemfile.rails-3.1 +0 -2
- data/Gemfile.rails-3.2 +0 -2
- data/Gemfile.rails-4.0 +0 -2
- data/Gemfile.rails-4.1 +0 -2
- data/Gemfile.rails-4.2 +0 -2
- data/Gemfile.rails-5.0 +1 -3
- data/README.md +5 -4
- data/lib/bullet/active_record3.rb +34 -3
- data/lib/bullet/active_record3x.rb +34 -3
- data/lib/bullet/active_record4.rb +34 -3
- data/lib/bullet/active_record41.rb +19 -0
- data/lib/bullet/active_record42.rb +37 -0
- data/lib/bullet/active_record5.rb +61 -48
- data/lib/bullet/version.rb +1 -1
- data/lib/bullet.rb +16 -2
- data/spec/bullet/rack_spec.rb +4 -4
- data/spec/bullet_spec.rb +43 -0
- data/spec/integration/active_record3/association_spec.rb +21 -1
- data/spec/integration/active_record4/association_spec.rb +21 -1
- data/spec/integration/active_record5/association_spec.rb +21 -1
- data/spec/spec_helper.rb +0 -3
- data/spec/support/sqlite_seed.rb +1 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ed73722e74144833068cf4572e3624687a9db64b
|
|
4
|
+
data.tar.gz: e882a8f5c7e4bfbe1d37254e1255ed79fc3f3948
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a62b1a339dccad8b79e97971c8d7fc73f977eb9d0b1c19758f59259e85531116fb57a9ef51c90e013d6051a27616ec861380d0940f658102155a163f52eb1873
|
|
7
|
+
data.tar.gz: de637d2bb853c67a5e7f2b269f698b18b59a481f5988025407d094e0442df03de805bc3890945e49accba76d3ae3c7a62c4185a8fde8d584550eac251a281836
|
data/.travis.yml
CHANGED
|
@@ -5,7 +5,7 @@ rvm:
|
|
|
5
5
|
- 2.0
|
|
6
6
|
- 2.1
|
|
7
7
|
- 2.2
|
|
8
|
-
- 2.
|
|
8
|
+
- 2.3.0
|
|
9
9
|
gemfile:
|
|
10
10
|
- Gemfile.rails-5.0
|
|
11
11
|
- Gemfile.rails-4.2
|
|
@@ -63,14 +63,14 @@ matrix:
|
|
|
63
63
|
gemfile: Gemfile.rails-3.0
|
|
64
64
|
- rvm: 2.1
|
|
65
65
|
gemfile: Gemfile.rails-5.0
|
|
66
|
-
- rvm: 2.2
|
|
67
|
-
gemfile: Gemfile.rails-5.0
|
|
68
66
|
- rvm: 2.2
|
|
69
67
|
gemfile: Gemfile.rails-3.0
|
|
70
68
|
- rvm: 2.2
|
|
71
69
|
gemfile: Gemfile.rails-3.1
|
|
72
70
|
- rvm: 2.2
|
|
73
71
|
gemfile: Gemfile.rails-3.2
|
|
72
|
+
- rvm: 2.2
|
|
73
|
+
gemfile: Gemfile.rails-5.0
|
|
74
74
|
- rvm: 2.2
|
|
75
75
|
gemfile: Gemfile.mongoid-3.1
|
|
76
76
|
- rvm: 2.2
|
|
@@ -85,23 +85,23 @@ matrix:
|
|
|
85
85
|
gemfile: Gemfile.mongoid-2.5
|
|
86
86
|
- rvm: 2.2
|
|
87
87
|
gemfile: Gemfile.mongoid-2.4
|
|
88
|
-
- rvm: 2.
|
|
88
|
+
- rvm: 2.3.0
|
|
89
89
|
gemfile: Gemfile.rails-3.0
|
|
90
|
-
- rvm: 2.
|
|
90
|
+
- rvm: 2.3.0
|
|
91
91
|
gemfile: Gemfile.rails-3.1
|
|
92
|
-
- rvm: 2.
|
|
92
|
+
- rvm: 2.3.0
|
|
93
93
|
gemfile: Gemfile.rails-3.2
|
|
94
|
-
- rvm: 2.
|
|
94
|
+
- rvm: 2.3.0
|
|
95
95
|
gemfile: Gemfile.mongoid-3.1
|
|
96
|
-
- rvm: 2.
|
|
96
|
+
- rvm: 2.3.0
|
|
97
97
|
gemfile: Gemfile.mongoid-3.0
|
|
98
|
-
- rvm: 2.
|
|
98
|
+
- rvm: 2.3.0
|
|
99
99
|
gemfile: Gemfile.mongoid-2.8
|
|
100
|
-
- rvm: 2.
|
|
100
|
+
- rvm: 2.3.0
|
|
101
101
|
gemfile: Gemfile.mongoid-2.7
|
|
102
|
-
- rvm: 2.
|
|
102
|
+
- rvm: 2.3.0
|
|
103
103
|
gemfile: Gemfile.mongoid-2.6
|
|
104
|
-
- rvm: 2.
|
|
104
|
+
- rvm: 2.3.0
|
|
105
105
|
gemfile: Gemfile.mongoid-2.5
|
|
106
|
-
- rvm: 2.
|
|
106
|
+
- rvm: 2.3.0
|
|
107
107
|
gemfile: Gemfile.mongoid-2.4
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
# Next Release
|
|
2
2
|
|
|
3
|
-
## 5.
|
|
3
|
+
## 5.3.0 (15/08/2016)
|
|
4
|
+
|
|
5
|
+
* Fix false alert on through association with join sql #301
|
|
6
|
+
* Fix association.target in through_association can be singular #302
|
|
7
|
+
* Support find_by_sql #303
|
|
8
|
+
* Fix env REQUEST_URI
|
|
9
|
+
|
|
10
|
+
## 5.2.0 (07/26/2016)
|
|
11
|
+
|
|
12
|
+
* Fix `has_cached_counter?` is not defined in HABTM #297
|
|
13
|
+
* Fix false alert if preloaded association has no records #260
|
|
14
|
+
* Support Rails 5.0.0
|
|
15
|
+
|
|
16
|
+
## 5.1.0 (05/21/2016)
|
|
4
17
|
|
|
5
18
|
* Fix false alert when `empty?` used with `counter_cache`
|
|
6
19
|
* Fix `alias_method_chain` deprecation for rails 5
|
|
@@ -8,7 +21,7 @@
|
|
|
8
21
|
* Fix false alert when querying immediately after creation
|
|
9
22
|
* Fix UnusedEagerLoading bug when multiple eager loading query include same objects
|
|
10
23
|
|
|
11
|
-
## 5.0.0 (01/06/
|
|
24
|
+
## 5.0.0 (01/06/2016)
|
|
12
25
|
|
|
13
26
|
* Support Rails 5.0.0.beta1
|
|
14
27
|
* Fix `has_many :through` infinite loop issue
|
data/Gemfile.mongoid-2.4
CHANGED
data/Gemfile.mongoid-2.5
CHANGED
data/Gemfile.mongoid-2.6
CHANGED
data/Gemfile.mongoid-2.7
CHANGED
data/Gemfile.mongoid-2.8
CHANGED
data/Gemfile.mongoid-3.0
CHANGED
data/Gemfile.mongoid-3.1
CHANGED
data/Gemfile.mongoid-4.0
CHANGED
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/Gemfile.rails-5.0
CHANGED
|
@@ -2,15 +2,13 @@ source "https://rubygems.org"
|
|
|
2
2
|
|
|
3
3
|
gemspec
|
|
4
4
|
|
|
5
|
-
gem 'rails', '5.0.0
|
|
5
|
+
gem 'rails', '5.0.0'
|
|
6
6
|
gem 'sqlite3'
|
|
7
7
|
gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
|
|
8
8
|
gem 'activerecord-import'
|
|
9
9
|
|
|
10
10
|
gem "rspec"
|
|
11
11
|
|
|
12
|
-
gem 'coveralls', require: false
|
|
13
|
-
|
|
14
12
|
platforms :rbx do
|
|
15
13
|
gem 'rubysl', '~> 2.0'
|
|
16
14
|
gem 'rubinius-developer_tools'
|
data/README.md
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
[](http://badge.fury.io/rb/bullet)
|
|
4
4
|
[](http://travis-ci.org/flyerhzm/bullet)
|
|
5
|
-
[](https://coveralls.io/r/flyerhzm/bullet)
|
|
6
5
|
<a href="https://codeclimate.com/github/flyerhzm/bullet"><img src="https://codeclimate.com/github/flyerhzm/bullet.png" /></a>
|
|
7
6
|
[](http://coderwall.com/flyerhzm)
|
|
8
7
|
|
|
@@ -63,7 +62,7 @@ config.after_initialize do
|
|
|
63
62
|
Bullet.add_footer = true
|
|
64
63
|
Bullet.stacktrace_includes = [ 'your_gem', 'your_middleware' ]
|
|
65
64
|
Bullet.stacktrace_excludes = [ 'their_gem', 'their_middleware' ]
|
|
66
|
-
Bullet.slack = { webhook_url: 'http://some.slack.url',
|
|
65
|
+
Bullet.slack = { webhook_url: 'http://some.slack.url', channel: '#default', username: 'notifier' }
|
|
67
66
|
end
|
|
68
67
|
```
|
|
69
68
|
|
|
@@ -238,7 +237,9 @@ Bullet outputs some details info, to enable debug mode, set
|
|
|
238
237
|
|
|
239
238
|
## Demo
|
|
240
239
|
|
|
241
|
-
Bullet is designed to function as you browse through your application in development. To see it in action,
|
|
240
|
+
Bullet is designed to function as you browse through your application in development. To see it in action,
|
|
241
|
+
you can visit [https://github.com/flyerhzm/bullet_test](https://github.com/flyerhzm/bullet_test) or
|
|
242
|
+
follow these steps to create, detect, and fix example query problems.
|
|
242
243
|
|
|
243
244
|
1\. Create an example application
|
|
244
245
|
|
|
@@ -458,4 +459,4 @@ Meanwhile, there's a line appended to `log/bullet.log`
|
|
|
458
459
|
Post => [:comments]
|
|
459
460
|
```
|
|
460
461
|
|
|
461
|
-
Copyright (c) 2009 -
|
|
462
|
+
Copyright (c) 2009 - 2016 Richard Huang (flyerhzm@gmail.com), released under the MIT license
|
|
@@ -4,6 +4,25 @@ module Bullet
|
|
|
4
4
|
|
|
5
5
|
def self.enable
|
|
6
6
|
require 'active_record'
|
|
7
|
+
::ActiveRecord::Base.class_eval do
|
|
8
|
+
class <<self
|
|
9
|
+
alias_method :origin_find_by_sql, :find_by_sql
|
|
10
|
+
def find_by_sql(sql)
|
|
11
|
+
result = origin_find_by_sql(sql)
|
|
12
|
+
if Bullet.start?
|
|
13
|
+
if result.is_a? Array
|
|
14
|
+
Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
|
|
15
|
+
Bullet::Detector::CounterCache.add_possible_objects(result)
|
|
16
|
+
elsif result.is_a? ::ActiveRecord::Base
|
|
17
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(result)
|
|
18
|
+
Bullet::Detector::CounterCache.add_impossible_object(result)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
result
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
7
26
|
::ActiveRecord::Relation.class_eval do
|
|
8
27
|
alias_method :origin_to_a, :to_a
|
|
9
28
|
# if select a collection of objects, then these objects have possible to cause N+1 query.
|
|
@@ -134,6 +153,16 @@ module Bullet
|
|
|
134
153
|
origin_last(*args)
|
|
135
154
|
end
|
|
136
155
|
|
|
156
|
+
alias_method :origin_include?, :include?
|
|
157
|
+
def include?(object)
|
|
158
|
+
if Bullet.start?
|
|
159
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
160
|
+
end
|
|
161
|
+
origin_include?(object)
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
::ActiveRecord::Associations::HasManyAssociation.class_eval do
|
|
137
166
|
alias_method :origin_empty?, :empty?
|
|
138
167
|
def empty?
|
|
139
168
|
if Bullet.start? && !has_cached_counter?
|
|
@@ -141,13 +170,15 @@ module Bullet
|
|
|
141
170
|
end
|
|
142
171
|
origin_empty?
|
|
143
172
|
end
|
|
173
|
+
end
|
|
144
174
|
|
|
145
|
-
|
|
146
|
-
|
|
175
|
+
::ActiveRecord::Associations::HasAndBelongsToManyAssociation.class_eval do
|
|
176
|
+
alias_method :origin_empty?, :empty?
|
|
177
|
+
def empty?
|
|
147
178
|
if Bullet.start?
|
|
148
179
|
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
149
180
|
end
|
|
150
|
-
|
|
181
|
+
origin_empty?
|
|
151
182
|
end
|
|
152
183
|
end
|
|
153
184
|
|
|
@@ -2,6 +2,25 @@ module Bullet
|
|
|
2
2
|
module ActiveRecord
|
|
3
3
|
def self.enable
|
|
4
4
|
require 'active_record'
|
|
5
|
+
::ActiveRecord::Base.class_eval do
|
|
6
|
+
class <<self
|
|
7
|
+
alias_method :origin_find_by_sql, :find_by_sql
|
|
8
|
+
def find_by_sql(sql, binds = [])
|
|
9
|
+
result = origin_find_by_sql(sql, binds)
|
|
10
|
+
if Bullet.start?
|
|
11
|
+
if result.is_a? Array
|
|
12
|
+
Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
|
|
13
|
+
Bullet::Detector::CounterCache.add_possible_objects(result)
|
|
14
|
+
elsif result.is_a? ::ActiveRecord::Base
|
|
15
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(result)
|
|
16
|
+
Bullet::Detector::CounterCache.add_impossible_object(result)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
result
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
5
24
|
::ActiveRecord::Relation.class_eval do
|
|
6
25
|
alias_method :origin_to_a, :to_a
|
|
7
26
|
# if select a collection of objects, then these objects have possible to cause N+1 query.
|
|
@@ -116,6 +135,16 @@ module Bullet
|
|
|
116
135
|
origin_load_target
|
|
117
136
|
end
|
|
118
137
|
|
|
138
|
+
alias_method :origin_include?, :include?
|
|
139
|
+
def include?(object)
|
|
140
|
+
if Bullet.start?
|
|
141
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
142
|
+
end
|
|
143
|
+
origin_include?(object)
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
::ActiveRecord::Associations::HasManyAssociation.class_eval do
|
|
119
148
|
alias_method :origin_empty?, :empty?
|
|
120
149
|
def empty?
|
|
121
150
|
if Bullet.start? && !has_cached_counter?(@reflection)
|
|
@@ -123,13 +152,15 @@ module Bullet
|
|
|
123
152
|
end
|
|
124
153
|
origin_empty?
|
|
125
154
|
end
|
|
155
|
+
end
|
|
126
156
|
|
|
127
|
-
|
|
128
|
-
|
|
157
|
+
::ActiveRecord::Associations::HasAndBelongsToManyAssociation.class_eval do
|
|
158
|
+
alias_method :origin_empty?, :empty?
|
|
159
|
+
def empty?
|
|
129
160
|
if Bullet.start?
|
|
130
161
|
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
131
162
|
end
|
|
132
|
-
|
|
163
|
+
origin_empty?
|
|
133
164
|
end
|
|
134
165
|
end
|
|
135
166
|
|
|
@@ -2,6 +2,25 @@ module Bullet
|
|
|
2
2
|
module ActiveRecord
|
|
3
3
|
def self.enable
|
|
4
4
|
require 'active_record'
|
|
5
|
+
::ActiveRecord::Base.class_eval do
|
|
6
|
+
class <<self
|
|
7
|
+
alias_method :origin_find_by_sql, :find_by_sql
|
|
8
|
+
def find_by_sql(sql, binds = [])
|
|
9
|
+
result = origin_find_by_sql(sql, binds)
|
|
10
|
+
if Bullet.start?
|
|
11
|
+
if result.is_a? Array
|
|
12
|
+
Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
|
|
13
|
+
Bullet::Detector::CounterCache.add_possible_objects(result)
|
|
14
|
+
elsif result.is_a? ::ActiveRecord::Base
|
|
15
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(result)
|
|
16
|
+
Bullet::Detector::CounterCache.add_impossible_object(result)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
result
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
5
24
|
::ActiveRecord::Relation.class_eval do
|
|
6
25
|
alias_method :origin_to_a, :to_a
|
|
7
26
|
# if select a collection of objects, then these objects have possible to cause N+1 query.
|
|
@@ -116,6 +135,16 @@ module Bullet
|
|
|
116
135
|
origin_load_target
|
|
117
136
|
end
|
|
118
137
|
|
|
138
|
+
alias_method :origin_include?, :include?
|
|
139
|
+
def include?(object)
|
|
140
|
+
if Bullet.start?
|
|
141
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
142
|
+
end
|
|
143
|
+
origin_include?(object)
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
::ActiveRecord::Associations::HasManyAssociation.class_eval do
|
|
119
148
|
alias_method :origin_empty?, :empty?
|
|
120
149
|
def empty?
|
|
121
150
|
if Bullet.start? && !has_cached_counter?(@reflection)
|
|
@@ -123,13 +152,15 @@ module Bullet
|
|
|
123
152
|
end
|
|
124
153
|
origin_empty?
|
|
125
154
|
end
|
|
155
|
+
end
|
|
126
156
|
|
|
127
|
-
|
|
128
|
-
|
|
157
|
+
::ActiveRecord::Associations::HasAndBelongsToManyAssociation.class_eval do
|
|
158
|
+
alias_method :origin_empty?, :empty?
|
|
159
|
+
def empty?
|
|
129
160
|
if Bullet.start?
|
|
130
161
|
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
131
162
|
end
|
|
132
|
-
|
|
163
|
+
origin_empty?
|
|
133
164
|
end
|
|
134
165
|
end
|
|
135
166
|
|
|
@@ -2,6 +2,25 @@ module Bullet
|
|
|
2
2
|
module ActiveRecord
|
|
3
3
|
def self.enable
|
|
4
4
|
require 'active_record'
|
|
5
|
+
::ActiveRecord::Base.class_eval do
|
|
6
|
+
class <<self
|
|
7
|
+
alias_method :origin_find_by_sql, :find_by_sql
|
|
8
|
+
def find_by_sql(sql, binds = [])
|
|
9
|
+
result = origin_find_by_sql(sql, binds)
|
|
10
|
+
if Bullet.start?
|
|
11
|
+
if result.is_a? Array
|
|
12
|
+
Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
|
|
13
|
+
Bullet::Detector::CounterCache.add_possible_objects(result)
|
|
14
|
+
elsif result.is_a? ::ActiveRecord::Base
|
|
15
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(result)
|
|
16
|
+
Bullet::Detector::CounterCache.add_impossible_object(result)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
result
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
5
24
|
::ActiveRecord::Relation.class_eval do
|
|
6
25
|
alias_method :origin_to_a, :to_a
|
|
7
26
|
# if select a collection of objects, then these objects have possible to cause N+1 query.
|
|
@@ -18,6 +18,21 @@ module Bullet
|
|
|
18
18
|
end
|
|
19
19
|
result
|
|
20
20
|
end
|
|
21
|
+
|
|
22
|
+
alias_method :origin_find_by_sql, :find_by_sql
|
|
23
|
+
def find_by_sql(sql, binds = [])
|
|
24
|
+
result = origin_find_by_sql(sql, binds)
|
|
25
|
+
if Bullet.start?
|
|
26
|
+
if result.is_a? Array
|
|
27
|
+
Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
|
|
28
|
+
Bullet::Detector::CounterCache.add_possible_objects(result)
|
|
29
|
+
elsif result.is_a? ::ActiveRecord::Base
|
|
30
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(result)
|
|
31
|
+
Bullet::Detector::CounterCache.add_impossible_object(result)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
result
|
|
35
|
+
end
|
|
21
36
|
end
|
|
22
37
|
end
|
|
23
38
|
|
|
@@ -96,6 +111,7 @@ module Bullet
|
|
|
96
111
|
|
|
97
112
|
::ActiveRecord::Associations::JoinDependency.class_eval do
|
|
98
113
|
alias_method :origin_instantiate, :instantiate
|
|
114
|
+
alias_method :origin_construct, :construct
|
|
99
115
|
alias_method :origin_construct_model, :construct_model
|
|
100
116
|
|
|
101
117
|
def instantiate(result_set, aliases)
|
|
@@ -111,6 +127,27 @@ module Bullet
|
|
|
111
127
|
records
|
|
112
128
|
end
|
|
113
129
|
|
|
130
|
+
def construct(ar_parent, parent, row, rs, seen, model_cache, aliases)
|
|
131
|
+
if Bullet.start?
|
|
132
|
+
unless ar_parent.nil?
|
|
133
|
+
parent.children.each do |node|
|
|
134
|
+
key = aliases.column_alias(node, node.primary_key)
|
|
135
|
+
id = row[key]
|
|
136
|
+
if id.nil?
|
|
137
|
+
associations = node.reflection.name
|
|
138
|
+
Bullet::Detector::Association.add_object_associations(ar_parent, associations)
|
|
139
|
+
Bullet::Detector::NPlusOneQuery.call_association(ar_parent, associations)
|
|
140
|
+
@bullet_eager_loadings[ar_parent.class] ||= {}
|
|
141
|
+
@bullet_eager_loadings[ar_parent.class][ar_parent] ||= Set.new
|
|
142
|
+
@bullet_eager_loadings[ar_parent.class][ar_parent] << associations
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
origin_construct(ar_parent, parent, row, rs, seen, model_cache, aliases)
|
|
149
|
+
end
|
|
150
|
+
|
|
114
151
|
# call join associations
|
|
115
152
|
def construct_model(record, node, row, model_cache, id, aliases)
|
|
116
153
|
result = origin_construct_model(record, node, row, model_cache, id, aliases)
|
|
@@ -20,9 +20,9 @@ module Bullet
|
|
|
20
20
|
require 'active_record'
|
|
21
21
|
::ActiveRecord::Base.class_eval do
|
|
22
22
|
class <<self
|
|
23
|
-
alias_method :
|
|
24
|
-
def
|
|
25
|
-
result =
|
|
23
|
+
alias_method :origin_find_by_sql, :find_by_sql
|
|
24
|
+
def find_by_sql(sql, binds = [], preparable: nil)
|
|
25
|
+
result = origin_find_by_sql(sql, binds, preparable: nil)
|
|
26
26
|
if Bullet.start?
|
|
27
27
|
if result.is_a? Array
|
|
28
28
|
Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
|
|
@@ -40,38 +40,30 @@ module Bullet
|
|
|
40
40
|
::ActiveRecord::Base.prepend(SaveWithBulletSupport)
|
|
41
41
|
|
|
42
42
|
::ActiveRecord::Relation.class_eval do
|
|
43
|
-
alias_method :
|
|
43
|
+
alias_method :origin_records, :records
|
|
44
44
|
# if select a collection of objects, then these objects have possible to cause N+1 query.
|
|
45
45
|
# if select only one object, then the only one object has impossible to cause N+1 query.
|
|
46
|
-
def
|
|
47
|
-
|
|
46
|
+
def records
|
|
47
|
+
result = origin_records
|
|
48
48
|
if Bullet.start?
|
|
49
|
-
if
|
|
50
|
-
if
|
|
51
|
-
Bullet::Detector::NPlusOneQuery.add_possible_objects(
|
|
52
|
-
Bullet::Detector::CounterCache.add_possible_objects(
|
|
53
|
-
elsif
|
|
54
|
-
Bullet::Detector::NPlusOneQuery.add_impossible_object(
|
|
55
|
-
Bullet::Detector::CounterCache.add_impossible_object(
|
|
49
|
+
if result.first.class.name !~ /^HABTM_/
|
|
50
|
+
if result.size > 1
|
|
51
|
+
Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
|
|
52
|
+
Bullet::Detector::CounterCache.add_possible_objects(result)
|
|
53
|
+
elsif result.size == 1
|
|
54
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(result.first)
|
|
55
|
+
Bullet::Detector::CounterCache.add_impossible_object(result.first)
|
|
56
56
|
end
|
|
57
57
|
end
|
|
58
58
|
end
|
|
59
|
-
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
::ActiveRecord::Associations::Association.class_eval do
|
|
64
|
-
alias_method :origin_initialize, :initialize
|
|
65
|
-
def initialize(owner, reflection)
|
|
66
|
-
origin_initialize(owner, reflection)
|
|
67
|
-
reflection.set_owner owner
|
|
59
|
+
result
|
|
68
60
|
end
|
|
69
61
|
end
|
|
70
62
|
|
|
71
63
|
::ActiveRecord::Associations::Preloader.class_eval do
|
|
72
|
-
alias_method :
|
|
64
|
+
alias_method :origin_preloaders_for_one, :preloaders_for_one
|
|
73
65
|
|
|
74
|
-
def
|
|
66
|
+
def preloaders_for_one(association, records, scope)
|
|
75
67
|
if Bullet.start?
|
|
76
68
|
records.compact!
|
|
77
69
|
if records.first.class.name !~ /^HABTM_/
|
|
@@ -81,7 +73,7 @@ module Bullet
|
|
|
81
73
|
Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, association)
|
|
82
74
|
end
|
|
83
75
|
end
|
|
84
|
-
|
|
76
|
+
origin_preloaders_for_one(association, records, scope)
|
|
85
77
|
end
|
|
86
78
|
end
|
|
87
79
|
|
|
@@ -104,6 +96,7 @@ module Bullet
|
|
|
104
96
|
|
|
105
97
|
::ActiveRecord::Associations::JoinDependency.class_eval do
|
|
106
98
|
alias_method :origin_instantiate, :instantiate
|
|
99
|
+
alias_method :origin_construct, :construct
|
|
107
100
|
alias_method :origin_construct_model, :construct_model
|
|
108
101
|
|
|
109
102
|
def instantiate(result_set, aliases)
|
|
@@ -119,6 +112,27 @@ module Bullet
|
|
|
119
112
|
records
|
|
120
113
|
end
|
|
121
114
|
|
|
115
|
+
def construct(ar_parent, parent, row, rs, seen, model_cache, aliases)
|
|
116
|
+
if Bullet.start?
|
|
117
|
+
unless ar_parent.nil?
|
|
118
|
+
parent.children.each do |node|
|
|
119
|
+
key = aliases.column_alias(node, node.primary_key)
|
|
120
|
+
id = row[key]
|
|
121
|
+
if id.nil?
|
|
122
|
+
associations = node.reflection.name
|
|
123
|
+
Bullet::Detector::Association.add_object_associations(ar_parent, associations)
|
|
124
|
+
Bullet::Detector::NPlusOneQuery.call_association(ar_parent, associations)
|
|
125
|
+
@bullet_eager_loadings[ar_parent.class] ||= {}
|
|
126
|
+
@bullet_eager_loadings[ar_parent.class][ar_parent] ||= Set.new
|
|
127
|
+
@bullet_eager_loadings[ar_parent.class][ar_parent] << associations
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
origin_construct(ar_parent, parent, row, rs, seen, model_cache, aliases)
|
|
134
|
+
end
|
|
135
|
+
|
|
122
136
|
# call join associations
|
|
123
137
|
def construct_model(record, node, row, model_cache, id, aliases)
|
|
124
138
|
result = origin_construct_model(record, node, row, model_cache, id, aliases)
|
|
@@ -143,7 +157,14 @@ module Bullet
|
|
|
143
157
|
records = origin_load_target
|
|
144
158
|
|
|
145
159
|
if Bullet.start?
|
|
146
|
-
|
|
160
|
+
if self.is_a? ::ActiveRecord::Associations::ThroughAssociation
|
|
161
|
+
Bullet::Detector::NPlusOneQuery.call_association(owner, through_reflection.name)
|
|
162
|
+
association = self.owner.association self.through_reflection.name
|
|
163
|
+
Array(association.target).each do |through_record|
|
|
164
|
+
Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name) unless @inversed
|
|
147
168
|
if records.first.class.name !~ /^HABTM_/
|
|
148
169
|
if records.size > 1
|
|
149
170
|
Bullet::Detector::NPlusOneQuery.add_possible_objects(records)
|
|
@@ -159,8 +180,8 @@ module Bullet
|
|
|
159
180
|
|
|
160
181
|
alias_method :origin_empty?, :empty?
|
|
161
182
|
def empty?
|
|
162
|
-
if Bullet.start? &&
|
|
163
|
-
Bullet::Detector::NPlusOneQuery.call_association(
|
|
183
|
+
if Bullet.start? && !reflection.has_cached_counter?
|
|
184
|
+
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
|
|
164
185
|
end
|
|
165
186
|
origin_empty?
|
|
166
187
|
end
|
|
@@ -168,7 +189,7 @@ module Bullet
|
|
|
168
189
|
alias_method :origin_include?, :include?
|
|
169
190
|
def include?(object)
|
|
170
191
|
if Bullet.start?
|
|
171
|
-
Bullet::Detector::NPlusOneQuery.call_association(
|
|
192
|
+
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
|
|
172
193
|
end
|
|
173
194
|
origin_include?(object)
|
|
174
195
|
end
|
|
@@ -180,9 +201,9 @@ module Bullet
|
|
|
180
201
|
def reader(force_reload = false)
|
|
181
202
|
result = origin_reader(force_reload)
|
|
182
203
|
if Bullet.start?
|
|
183
|
-
if
|
|
184
|
-
Bullet::Detector::NPlusOneQuery.call_association(
|
|
185
|
-
if Bullet::Detector::NPlusOneQuery.impossible?(
|
|
204
|
+
if owner.class.name !~ /^HABTM_/ && !@inversed
|
|
205
|
+
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
|
|
206
|
+
if Bullet::Detector::NPlusOneQuery.impossible?(owner)
|
|
186
207
|
Bullet::Detector::NPlusOneQuery.add_impossible_object(result) if result
|
|
187
208
|
else
|
|
188
209
|
Bullet::Detector::NPlusOneQuery.add_possible_objects(result) if result
|
|
@@ -196,28 +217,20 @@ module Bullet
|
|
|
196
217
|
::ActiveRecord::Associations::HasManyAssociation.class_eval do
|
|
197
218
|
alias_method :origin_many_empty?, :empty?
|
|
198
219
|
def empty?
|
|
199
|
-
Thread.current[:bullet_collection_empty] = true
|
|
200
220
|
result = origin_many_empty?
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
221
|
+
if Bullet.start? && !reflection.has_cached_counter?
|
|
222
|
+
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
|
|
204
223
|
end
|
|
205
224
|
result
|
|
206
225
|
end
|
|
207
|
-
end
|
|
208
|
-
|
|
209
|
-
::ActiveRecord::Reflection::AbstractReflection.class_eval do
|
|
210
|
-
def set_owner(owner)
|
|
211
|
-
@owner = owner
|
|
212
|
-
end
|
|
213
226
|
|
|
214
|
-
alias_method :
|
|
215
|
-
def
|
|
216
|
-
result =
|
|
217
|
-
if Bullet.start? && !result && !
|
|
218
|
-
Bullet::Detector::CounterCache.add_counter_cache(
|
|
227
|
+
alias_method :origin_count_records, :count_records
|
|
228
|
+
def count_records
|
|
229
|
+
result = reflection.has_cached_counter?
|
|
230
|
+
if Bullet.start? && !result && !self.is_a?(::ActiveRecord::Associations::ThroughAssociation)
|
|
231
|
+
Bullet::Detector::CounterCache.add_counter_cache(owner, reflection.name)
|
|
219
232
|
end
|
|
220
|
-
|
|
233
|
+
origin_count_records
|
|
221
234
|
end
|
|
222
235
|
end
|
|
223
236
|
end
|
data/lib/bullet/version.rb
CHANGED
data/lib/bullet.rb
CHANGED
|
@@ -166,8 +166,9 @@ module Bullet
|
|
|
166
166
|
end
|
|
167
167
|
|
|
168
168
|
def perform_out_of_channel_notifications(env = {})
|
|
169
|
+
request_uri = env['REQUEST_URI'] || build_request_uri(env)
|
|
169
170
|
for_each_active_notifier_with_notification do |notification|
|
|
170
|
-
notification.url =
|
|
171
|
+
notification.url = request_uri
|
|
171
172
|
notification.notify_out_of_channel
|
|
172
173
|
end
|
|
173
174
|
end
|
|
@@ -190,17 +191,22 @@ module Bullet
|
|
|
190
191
|
end
|
|
191
192
|
|
|
192
193
|
def profile
|
|
194
|
+
return_value = nil
|
|
193
195
|
if Bullet.enable?
|
|
194
196
|
begin
|
|
195
197
|
Bullet.start_request
|
|
196
198
|
|
|
197
|
-
yield
|
|
199
|
+
return_value = yield
|
|
198
200
|
|
|
199
201
|
Bullet.perform_out_of_channel_notifications if Bullet.notification?
|
|
200
202
|
ensure
|
|
201
203
|
Bullet.end_request
|
|
202
204
|
end
|
|
205
|
+
else
|
|
206
|
+
return_value = yield
|
|
203
207
|
end
|
|
208
|
+
|
|
209
|
+
return_value
|
|
204
210
|
end
|
|
205
211
|
|
|
206
212
|
private
|
|
@@ -212,5 +218,13 @@ module Bullet
|
|
|
212
218
|
end
|
|
213
219
|
end
|
|
214
220
|
end
|
|
221
|
+
|
|
222
|
+
def build_request_uri(env)
|
|
223
|
+
if env['QUERY_STRING'].present?
|
|
224
|
+
"#{env['PATH_INFO']}?#{env['QUERY_STRING']}"
|
|
225
|
+
else
|
|
226
|
+
env['PATH_INFO']
|
|
227
|
+
end
|
|
228
|
+
end
|
|
215
229
|
end
|
|
216
230
|
end
|
data/spec/bullet/rack_spec.rb
CHANGED
|
@@ -60,7 +60,7 @@ module Bullet
|
|
|
60
60
|
it "should return original response body" do
|
|
61
61
|
expected_response = Support::ResponseDouble.new "Actual body"
|
|
62
62
|
app.response = expected_response
|
|
63
|
-
_, _, response = middleware.call(
|
|
63
|
+
_, _, response = middleware.call({})
|
|
64
64
|
expect(response).to eq(expected_response)
|
|
65
65
|
end
|
|
66
66
|
|
|
@@ -68,7 +68,7 @@ module Bullet
|
|
|
68
68
|
expect(Bullet).to receive(:notification?).and_return(true)
|
|
69
69
|
expect(Bullet).to receive(:gather_inline_notifications).and_return("<bullet></bullet>")
|
|
70
70
|
expect(Bullet).to receive(:perform_out_of_channel_notifications)
|
|
71
|
-
status, headers, response = middleware.call(
|
|
71
|
+
status, headers, response = middleware.call({"Content-Type" => "text/html"})
|
|
72
72
|
expect(headers["Content-Length"]).to eq("56")
|
|
73
73
|
expect(response).to eq(["<html><head></head><body><bullet></bullet></body></html>"])
|
|
74
74
|
end
|
|
@@ -79,7 +79,7 @@ module Bullet
|
|
|
79
79
|
app.response = response
|
|
80
80
|
expect(Bullet).to receive(:notification?).and_return(true)
|
|
81
81
|
expect(Bullet).to receive(:gather_inline_notifications).and_return("<bullet></bullet>")
|
|
82
|
-
status, headers, response = middleware.call(
|
|
82
|
+
status, headers, response = middleware.call({"Content-Type" => "text/html"})
|
|
83
83
|
expect(headers["Content-Length"]).to eq("58")
|
|
84
84
|
end
|
|
85
85
|
end
|
|
@@ -89,7 +89,7 @@ module Bullet
|
|
|
89
89
|
|
|
90
90
|
it "should not call Bullet.start_request" do
|
|
91
91
|
expect(Bullet).not_to receive(:start_request)
|
|
92
|
-
middleware.call(
|
|
92
|
+
middleware.call({})
|
|
93
93
|
end
|
|
94
94
|
end
|
|
95
95
|
end
|
data/spec/bullet_spec.rb
CHANGED
|
@@ -94,4 +94,47 @@ describe Bullet, focused: true do
|
|
|
94
94
|
end
|
|
95
95
|
end
|
|
96
96
|
end
|
|
97
|
+
|
|
98
|
+
describe '#perform_out_of_channel_notifications' do
|
|
99
|
+
let(:notification) { double }
|
|
100
|
+
|
|
101
|
+
before do
|
|
102
|
+
allow(Bullet).to receive(:for_each_active_notifier_with_notification).and_yield(notification)
|
|
103
|
+
allow(notification).to receive(:notify_out_of_channel)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
context 'when called with no args' do
|
|
107
|
+
it 'should notification.url is nil' do
|
|
108
|
+
expect(notification).to receive(:url=).with(nil)
|
|
109
|
+
Bullet.perform_out_of_channel_notifications
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
context 'when called with Rack environment hash' do
|
|
114
|
+
let(:env) {
|
|
115
|
+
{
|
|
116
|
+
'PATH_INFO' => '/path',
|
|
117
|
+
'QUERY_STRING' => 'foo=bar',
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
context "when env['REQUEST_URI'] is nil" do
|
|
122
|
+
before { env['REQUEST_URI'] = nil }
|
|
123
|
+
|
|
124
|
+
it 'should notification.url is built' do
|
|
125
|
+
expect(notification).to receive(:url=).with('/path?foo=bar')
|
|
126
|
+
Bullet.perform_out_of_channel_notifications(env)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
context "when env['REQUEST_URI'] is present" do
|
|
131
|
+
before { env['REQUEST_URI'] = 'http://example.com/path' }
|
|
132
|
+
|
|
133
|
+
it "should notification.url is env['REQUEST_URI']" do
|
|
134
|
+
expect(notification).to receive(:url=).with(env['REQUEST_URI'])
|
|
135
|
+
Bullet.perform_out_of_channel_notifications(env)
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
97
140
|
end
|
|
@@ -13,6 +13,16 @@ if !mongoid? && active_record3?
|
|
|
13
13
|
expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Post, :comments)
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
+
it "should detect non preload post => comments for find_by_sql" do
|
|
17
|
+
Post.find_by_sql("SELECT * FROM posts").each do |post|
|
|
18
|
+
post.comments.map(&:name)
|
|
19
|
+
end
|
|
20
|
+
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
|
21
|
+
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
|
22
|
+
|
|
23
|
+
expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Post, :comments)
|
|
24
|
+
end
|
|
25
|
+
|
|
16
26
|
it "should detect preload with post => comments" do
|
|
17
27
|
Post.includes(:comments).each do |post|
|
|
18
28
|
post.comments.map(&:name)
|
|
@@ -214,7 +224,7 @@ if !mongoid? && active_record3?
|
|
|
214
224
|
context "post => comment" do
|
|
215
225
|
it "should detect unused preload with post => comments" do
|
|
216
226
|
Post.includes(:comments).each do |post|
|
|
217
|
-
post.comments.first.name
|
|
227
|
+
post.comments.first.name if post.comments.first
|
|
218
228
|
end
|
|
219
229
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
|
220
230
|
expect(Bullet::Detector::Association).not_to be_unused_preload_associations_for(Post, :comments)
|
|
@@ -453,6 +463,16 @@ if !mongoid? && active_record3?
|
|
|
453
463
|
|
|
454
464
|
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
|
455
465
|
end
|
|
466
|
+
|
|
467
|
+
it "should detect non preload student => teachers with empty?" do
|
|
468
|
+
Student.all.each do |student|
|
|
469
|
+
student.teachers.empty?
|
|
470
|
+
end
|
|
471
|
+
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
|
472
|
+
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
|
473
|
+
|
|
474
|
+
expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Student, :teachers)
|
|
475
|
+
end
|
|
456
476
|
end
|
|
457
477
|
end
|
|
458
478
|
|
|
@@ -13,6 +13,16 @@ if !mongoid? && active_record4?
|
|
|
13
13
|
expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Post, :comments)
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
+
it "should detect non preload post => comments for find_by_sql" do
|
|
17
|
+
Post.find_by_sql("SELECT * FROM posts").each do |post|
|
|
18
|
+
post.comments.map(&:name)
|
|
19
|
+
end
|
|
20
|
+
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
|
21
|
+
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
|
22
|
+
|
|
23
|
+
expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Post, :comments)
|
|
24
|
+
end
|
|
25
|
+
|
|
16
26
|
it "should detect preload with post => comments" do
|
|
17
27
|
Post.includes(:comments).each do |post|
|
|
18
28
|
post.comments.map(&:name)
|
|
@@ -214,7 +224,7 @@ if !mongoid? && active_record4?
|
|
|
214
224
|
context "post => comment" do
|
|
215
225
|
it "should detect unused preload with post => comments" do
|
|
216
226
|
Post.includes(:comments).each do |post|
|
|
217
|
-
post.comments.first.name
|
|
227
|
+
post.comments.first.name if post.comments.first
|
|
218
228
|
end
|
|
219
229
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
|
220
230
|
expect(Bullet::Detector::Association).not_to be_unused_preload_associations_for(Post, :comments)
|
|
@@ -465,6 +475,16 @@ if !mongoid? && active_record4?
|
|
|
465
475
|
|
|
466
476
|
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
|
467
477
|
end
|
|
478
|
+
|
|
479
|
+
it "should detect non preload student => teachers with empty?" do
|
|
480
|
+
Student.all.each do |student|
|
|
481
|
+
student.teachers.empty?
|
|
482
|
+
end
|
|
483
|
+
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
|
484
|
+
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
|
485
|
+
|
|
486
|
+
expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Student, :teachers)
|
|
487
|
+
end
|
|
468
488
|
end
|
|
469
489
|
end
|
|
470
490
|
|
|
@@ -13,6 +13,16 @@ if !mongoid? && active_record5?
|
|
|
13
13
|
expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Post, :comments)
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
+
it "should detect non preload post => comments for find_by_sql" do
|
|
17
|
+
Post.find_by_sql("SELECT * FROM posts").each do |post|
|
|
18
|
+
post.comments.map(&:name)
|
|
19
|
+
end
|
|
20
|
+
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
|
21
|
+
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
|
22
|
+
|
|
23
|
+
expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Post, :comments)
|
|
24
|
+
end
|
|
25
|
+
|
|
16
26
|
it "should detect preload with post => comments" do
|
|
17
27
|
Post.includes(:comments).each do |post|
|
|
18
28
|
post.comments.map(&:name)
|
|
@@ -214,7 +224,7 @@ if !mongoid? && active_record5?
|
|
|
214
224
|
context "post => comment" do
|
|
215
225
|
it "should detect unused preload with post => comments" do
|
|
216
226
|
Post.includes(:comments).each do |post|
|
|
217
|
-
post.comments.first.name
|
|
227
|
+
post.comments.first.name if post.comments.first
|
|
218
228
|
end
|
|
219
229
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
|
220
230
|
expect(Bullet::Detector::Association).not_to be_unused_preload_associations_for(Post, :comments)
|
|
@@ -465,6 +475,16 @@ if !mongoid? && active_record5?
|
|
|
465
475
|
|
|
466
476
|
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
|
467
477
|
end
|
|
478
|
+
|
|
479
|
+
it "should detect non preload student => teachers with empty?" do
|
|
480
|
+
Student.all.each do |student|
|
|
481
|
+
student.teachers.empty?
|
|
482
|
+
end
|
|
483
|
+
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
|
484
|
+
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
|
485
|
+
|
|
486
|
+
expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Student, :teachers)
|
|
487
|
+
end
|
|
468
488
|
end
|
|
469
489
|
end
|
|
470
490
|
|
data/spec/spec_helper.rb
CHANGED
|
@@ -30,9 +30,6 @@ $LOAD_PATH.unshift(MODELS)
|
|
|
30
30
|
SUPPORT = File.join(File.dirname(__FILE__), "support")
|
|
31
31
|
Dir[ File.join(SUPPORT, "*.rb") ].reject { |filename| filename =~ /_seed.rb$/ }.sort.each { |file| require file }
|
|
32
32
|
|
|
33
|
-
require 'coveralls'
|
|
34
|
-
Coveralls.wear!
|
|
35
|
-
|
|
36
33
|
RSpec.configure do |config|
|
|
37
34
|
config.extend Bullet::Dependency
|
|
38
35
|
|
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)
|
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.3.0
|
|
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-08-15 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|