bullet 7.0.0 → 7.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +1 -1
- data/CHANGELOG.md +14 -0
- data/README.md +20 -18
- data/lib/bullet/active_record5.rb +1 -1
- data/lib/bullet/active_record52.rb +2 -2
- data/lib/bullet/active_record60.rb +2 -2
- data/lib/bullet/active_record61.rb +2 -2
- data/lib/bullet/active_record70.rb +16 -2
- data/lib/bullet/bullet_xhr.js +3 -3
- data/lib/bullet/detector/counter_cache.rb +2 -2
- data/lib/bullet/detector/n_plus_one_query.rb +3 -3
- data/lib/bullet/detector/unused_eager_loading.rb +2 -2
- data/lib/bullet/rack.rb +2 -1
- data/lib/bullet/version.rb +1 -1
- data/lib/bullet.rb +1 -46
- data/lib/generators/bullet/install_generator.rb +0 -1
- data/spec/bullet/detector/n_plus_one_query_spec.rb +1 -1
- data/spec/bullet/notification/base_spec.rb +4 -4
- data/spec/bullet/rack_spec.rb +5 -6
- data/spec/bullet_spec.rb +0 -29
- data/spec/integration/active_record/association_spec.rb +10 -0
- data/spec/models/role.rb +7 -0
- data/spec/models/user.rb +1 -0
- data/spec/support/sqlite_seed.rb +18 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ad1f81292cc89778a41c6dd178bbfb6342fe1b69c4e57c3fdad0d8003d97b525
|
4
|
+
data.tar.gz: 5c1c8113f6e03ecdb449bce5e12273b969f29c323a5bb802c13c0539ea439a69
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f0d4d73910f96ab8c6ae5b6b1bc58de547c2c32a7c689c2984778465dae29d2c2cae81c23699b3848d2eaef30223db66bcca6ccb421b9078d5616f497421d45
|
7
|
+
data.tar.gz: 3b9001966918da22bfe7b2960526ac0db471a75e79e7939b099bebe3dde1fb27ea69b1afbdec0fcc98a6cb4260b845b5551a1a07cec036207c885be4e14ef7b9
|
data/.github/workflows/main.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
## Next Release
|
2
2
|
|
3
|
+
## 7.0.3 (08/13/2022)
|
4
|
+
|
5
|
+
* Replace `Array()` with `Array.wrap()`
|
6
|
+
|
7
|
+
## 7.0.2 (05/31/2022)
|
8
|
+
|
9
|
+
* Drop growl support
|
10
|
+
* Do not check html tag in Bullet::Rack anymore
|
11
|
+
|
12
|
+
## 7.0.1 (01/15/2022)
|
13
|
+
|
14
|
+
* Get rid of *_whitelist methods
|
15
|
+
* Hack ActiveRecord::Associations::Preloader::Batch in rails 7
|
16
|
+
|
3
17
|
## 7.0.0 (12/18/2021)
|
4
18
|
|
5
19
|
* Support rails 7
|
data/README.md
CHANGED
@@ -49,7 +49,7 @@ mongoid.
|
|
49
49
|
|
50
50
|
## Configuration
|
51
51
|
|
52
|
-
Bullet won't
|
52
|
+
Bullet won't enable any notification systems unless you tell it to explicitly. Append to
|
53
53
|
`config/environments/development.rb` initializer with the following code:
|
54
54
|
|
55
55
|
```ruby
|
@@ -59,7 +59,6 @@ config.after_initialize do
|
|
59
59
|
Bullet.alert = true
|
60
60
|
Bullet.bullet_logger = true
|
61
61
|
Bullet.console = true
|
62
|
-
Bullet.growl = true
|
63
62
|
Bullet.xmpp = { :account => 'bullets_account@jabber.org',
|
64
63
|
:password => 'bullets_password_for_jabber',
|
65
64
|
:receiver => 'your_account@jabber.org',
|
@@ -85,7 +84,6 @@ The code above will enable all of the Bullet notification systems:
|
|
85
84
|
* `Bullet.alert`: pop up a JavaScript alert in the browser
|
86
85
|
* `Bullet.bullet_logger`: log to the Bullet log file (Rails.root/log/bullet.log)
|
87
86
|
* `Bullet.console`: log warnings to your browser's console.log (Safari/Webkit browsers or Firefox w/Firebug installed)
|
88
|
-
* `Bullet.growl`: pop up Growl warnings if your system has Growl installed. Requires a little bit of configuration
|
89
87
|
* `Bullet.xmpp`: send XMPP/Jabber notifications to the receiver indicated. Note that the code will currently not handle the adding of contacts, so you will need to make both accounts indicated know each other manually before you will receive any notifications. If you restart the development server frequently, the 'coming online' sound for the Bullet account may start to annoy - in this case set :show_online_status to false; you will still get notifications, but the Bullet account won't announce it's online status anymore.
|
90
88
|
* `Bullet.rails_logger`: add warnings directly to the Rails log
|
91
89
|
* `Bullet.honeybadger`: add notifications to Honeybadger
|
@@ -156,25 +154,26 @@ The Bullet log `log/bullet.log` will look something like this:
|
|
156
154
|
* N+1 Query:
|
157
155
|
|
158
156
|
```
|
159
|
-
2009-08-25 20:40:17[INFO]
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
/Users/richard/Downloads/test/app/views/posts/index.html.erb:8:in `each'
|
164
|
-
/Users/richard/Downloads/test/app/
|
165
|
-
/Users/richard/Downloads/test/app/controllers/posts_controller.rb:7:in `index'
|
157
|
+
2009-08-25 20:40:17[INFO] USE eager loading detected:
|
158
|
+
Post => [:comments]·
|
159
|
+
Add to your query: .includes([:comments])
|
160
|
+
2009-08-25 20:40:17[INFO] Call stack
|
161
|
+
/Users/richard/Downloads/test/app/views/posts/index.html.erb:8:in `each'
|
162
|
+
/Users/richard/Downloads/test/app/controllers/posts_controller.rb:7:in `index'
|
166
163
|
```
|
167
164
|
|
168
|
-
The first
|
165
|
+
The first log entry is a notification that N+1 queries have been encountered. The remaining entry is a stack trace so you can find exactly where the queries were invoked in your code, and fix them.
|
169
166
|
|
170
167
|
* Unused eager loading:
|
171
168
|
|
172
169
|
```
|
173
|
-
2009-08-25 20:53:56[INFO]
|
174
|
-
|
170
|
+
2009-08-25 20:53:56[INFO] AVOID eager loading detected
|
171
|
+
Post => [:comments]·
|
172
|
+
Remove from your query: .includes([:comments])
|
173
|
+
2009-08-25 20:53:56[INFO] Call stack
|
175
174
|
```
|
176
175
|
|
177
|
-
These
|
176
|
+
These lines are notifications that unused eager loadings have been encountered.
|
178
177
|
|
179
178
|
* Need counter cache:
|
180
179
|
|
@@ -183,10 +182,14 @@ These two lines are notifications that unused eager loadings have been encounter
|
|
183
182
|
Post => [:comments]
|
184
183
|
```
|
185
184
|
|
186
|
-
##
|
185
|
+
## XMPP/Jabber and Airbrake Support
|
187
186
|
|
188
187
|
see [https://github.com/flyerhzm/uniform_notifier](https://github.com/flyerhzm/uniform_notifier)
|
189
188
|
|
189
|
+
## Growl Support
|
190
|
+
|
191
|
+
Growl support is dropped from uniform_notifier 1.16.0, if you still want it, please use uniform_notifier 1.15.0.
|
192
|
+
|
190
193
|
## Important
|
191
194
|
|
192
195
|
If you find Bullet does not work for you, *please disable your browser's cache*.
|
@@ -270,8 +273,7 @@ Bullet outputs some details info, to enable debug mode, set
|
|
270
273
|
## Demo
|
271
274
|
|
272
275
|
Bullet is designed to function as you browse through your application in development. To see it in action,
|
273
|
-
you can
|
274
|
-
follow these steps to create, detect, and fix example query problems.
|
276
|
+
you can follow these steps to create, detect, and fix example query problems.
|
275
277
|
|
276
278
|
1\. Create an example application
|
277
279
|
|
@@ -482,4 +484,4 @@ Meanwhile, there's a line appended to `log/bullet.log`
|
|
482
484
|
Post => [:comments]
|
483
485
|
```
|
484
486
|
|
485
|
-
Copyright (c) 2009 -
|
487
|
+
Copyright (c) 2009 - 2022 Richard Huang (flyerhzm@gmail.com), released under the MIT license
|
@@ -179,7 +179,7 @@ module Bullet
|
|
179
179
|
refl = reflection.through_reflection
|
180
180
|
Bullet::Detector::NPlusOneQuery.call_association(owner, refl.name)
|
181
181
|
association = owner.association refl.name
|
182
|
-
Array(association.target).each do |through_record|
|
182
|
+
Array.wrap(association.target).each do |through_record|
|
183
183
|
Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
|
184
184
|
end
|
185
185
|
|
@@ -152,7 +152,7 @@ module Bullet
|
|
152
152
|
if is_a? ::ActiveRecord::Associations::ThroughAssociation
|
153
153
|
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
|
154
154
|
association = owner.association reflection.through_reflection.name
|
155
|
-
Array(association.target).each do |through_record|
|
155
|
+
Array.wrap(association.target).each do |through_record|
|
156
156
|
Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
|
157
157
|
end
|
158
158
|
|
@@ -199,7 +199,7 @@ module Bullet
|
|
199
199
|
if is_a? ::ActiveRecord::Associations::ThroughAssociation
|
200
200
|
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
|
201
201
|
association = owner.association reflection.through_reflection.name
|
202
|
-
Array(association.target).each do |through_record|
|
202
|
+
Array.wrap(association.target).each do |through_record|
|
203
203
|
Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
|
204
204
|
end
|
205
205
|
|
@@ -179,7 +179,7 @@ module Bullet
|
|
179
179
|
if is_a? ::ActiveRecord::Associations::ThroughAssociation
|
180
180
|
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
|
181
181
|
association = owner.association(reflection.through_reflection.name)
|
182
|
-
Array(association.target).each do |through_record|
|
182
|
+
Array.wrap(association.target).each do |through_record|
|
183
183
|
Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
|
184
184
|
end
|
185
185
|
|
@@ -226,7 +226,7 @@ module Bullet
|
|
226
226
|
if is_a? ::ActiveRecord::Associations::ThroughAssociation
|
227
227
|
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
|
228
228
|
association = owner.association(reflection.through_reflection.name)
|
229
|
-
Array(association.target).each do |through_record|
|
229
|
+
Array.wrap(association.target).each do |through_record|
|
230
230
|
Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
|
231
231
|
end
|
232
232
|
|
@@ -179,7 +179,7 @@ module Bullet
|
|
179
179
|
if is_a? ::ActiveRecord::Associations::ThroughAssociation
|
180
180
|
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
|
181
181
|
association = owner.association(reflection.through_reflection.name)
|
182
|
-
Array(association.target).each do |through_record|
|
182
|
+
Array.wrap(association.target).each do |through_record|
|
183
183
|
Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
|
184
184
|
end
|
185
185
|
|
@@ -226,7 +226,7 @@ module Bullet
|
|
226
226
|
if is_a? ::ActiveRecord::Associations::ThroughAssociation
|
227
227
|
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
|
228
228
|
association = owner.association(reflection.through_reflection.name)
|
229
|
-
Array(association.target).each do |through_record|
|
229
|
+
Array.wrap(association.target).each do |through_record|
|
230
230
|
Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
|
231
231
|
end
|
232
232
|
|
@@ -60,6 +60,20 @@ module Bullet
|
|
60
60
|
end
|
61
61
|
)
|
62
62
|
|
63
|
+
::ActiveRecord::Associations::Preloader::Batch.prepend(
|
64
|
+
Module.new do
|
65
|
+
def call
|
66
|
+
if Bullet.start?
|
67
|
+
@preloaders.each do |preloader|
|
68
|
+
preloader.records.each { |record| Bullet::Detector::Association.add_object_associations(record, preloader.associations) }
|
69
|
+
Bullet::Detector::UnusedEagerLoading.add_eager_loadings(preloader.records, preloader.associations)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
super
|
73
|
+
end
|
74
|
+
end
|
75
|
+
)
|
76
|
+
|
63
77
|
::ActiveRecord::Associations::Preloader::Branch.prepend(
|
64
78
|
Module.new do
|
65
79
|
def preloaders_for_reflection(reflection, reflection_records)
|
@@ -168,7 +182,7 @@ module Bullet
|
|
168
182
|
if is_a? ::ActiveRecord::Associations::ThroughAssociation
|
169
183
|
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
|
170
184
|
association = owner.association(reflection.through_reflection.name)
|
171
|
-
Array(association.target).each do |through_record|
|
185
|
+
Array.wrap(association.target).each do |through_record|
|
172
186
|
Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
|
173
187
|
end
|
174
188
|
|
@@ -215,7 +229,7 @@ module Bullet
|
|
215
229
|
if is_a? ::ActiveRecord::Associations::ThroughAssociation
|
216
230
|
Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
|
217
231
|
association = owner.association(reflection.through_reflection.name)
|
218
|
-
Array(association.target).each do |through_record|
|
232
|
+
Array.wrap(association.target).each do |through_record|
|
219
233
|
Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
|
220
234
|
end
|
221
235
|
|
data/lib/bullet/bullet_xhr.js
CHANGED
@@ -20,7 +20,7 @@
|
|
20
20
|
if (this.onload) {
|
21
21
|
this._storedOnload = this.onload;
|
22
22
|
}
|
23
|
-
this.onload = null
|
23
|
+
this.onload = null;
|
24
24
|
this.addEventListener("load", bulletXHROnload);
|
25
25
|
return Reflect.apply(oldSend, this, arguments);
|
26
26
|
}
|
@@ -31,7 +31,7 @@
|
|
31
31
|
) {
|
32
32
|
var bulletFooterText = this.getResponseHeader("X-bullet-footer-text");
|
33
33
|
if (bulletFooterText) {
|
34
|
-
setTimeout(function() {
|
34
|
+
setTimeout(function () {
|
35
35
|
var oldHtml = document.querySelector("#bullet-footer").innerHTML.split("<br>");
|
36
36
|
var header = oldHtml[0];
|
37
37
|
oldHtml = oldHtml.slice(1, oldHtml.length);
|
@@ -42,7 +42,7 @@
|
|
42
42
|
}
|
43
43
|
var bulletConsoleText = this.getResponseHeader("X-bullet-console-text");
|
44
44
|
if (bulletConsoleText && typeof console !== "undefined" && console.log) {
|
45
|
-
setTimeout(function() {
|
45
|
+
setTimeout(function () {
|
46
46
|
JSON.parse(bulletConsoleText).forEach((message) => {
|
47
47
|
if (console.groupCollapsed && console.groupEnd) {
|
48
48
|
console.groupCollapsed("Uniform Notifier");
|
@@ -20,7 +20,7 @@ module Bullet
|
|
20
20
|
return unless Bullet.start?
|
21
21
|
return unless Bullet.counter_cache_enable?
|
22
22
|
|
23
|
-
objects = Array(object_or_objects)
|
23
|
+
objects = Array.wrap(object_or_objects)
|
24
24
|
return if objects.map(&:bullet_primary_key_value).compact.empty?
|
25
25
|
|
26
26
|
Bullet.debug(
|
@@ -54,7 +54,7 @@ module Bullet
|
|
54
54
|
private
|
55
55
|
|
56
56
|
def create_notification(klazz, associations)
|
57
|
-
notify_associations = Array(associations) - Bullet.get_safelist_associations(:counter_cache, klazz)
|
57
|
+
notify_associations = Array.wrap(associations) - Bullet.get_safelist_associations(:counter_cache, klazz)
|
58
58
|
|
59
59
|
if notify_associations.present?
|
60
60
|
notice = Bullet::Notification::CounterCache.new klazz, notify_associations
|
@@ -7,7 +7,7 @@ module Bullet
|
|
7
7
|
extend StackTraceFilter
|
8
8
|
|
9
9
|
class << self
|
10
|
-
# executed when object.
|
10
|
+
# executed when object.associations is called.
|
11
11
|
# first, it keeps this method call for object.association.
|
12
12
|
# then, it checks if this associations call is unpreload.
|
13
13
|
# if it is, keeps this unpreload associations and caller.
|
@@ -33,7 +33,7 @@ module Bullet
|
|
33
33
|
return unless Bullet.start?
|
34
34
|
return unless Bullet.n_plus_one_query_enable?
|
35
35
|
|
36
|
-
objects = Array(object_or_objects)
|
36
|
+
objects = Array.wrap(object_or_objects)
|
37
37
|
return if objects.map(&:bullet_primary_key_value).compact.empty?
|
38
38
|
return if objects.all? { |obj| obj.class.name =~ /^HABTM_/ }
|
39
39
|
|
@@ -95,7 +95,7 @@ module Bullet
|
|
95
95
|
private
|
96
96
|
|
97
97
|
def create_notification(callers, klazz, associations)
|
98
|
-
notify_associations = Array(associations) - Bullet.get_safelist_associations(:n_plus_one_query, klazz)
|
98
|
+
notify_associations = Array.wrap(associations) - Bullet.get_safelist_associations(:n_plus_one_query, klazz)
|
99
99
|
|
100
100
|
if notify_associations.present?
|
101
101
|
notice = Bullet::Notification::NPlusOneQuery.new(callers, klazz, notify_associations)
|
@@ -10,7 +10,7 @@ module Bullet
|
|
10
10
|
# check if there are unused preload associations.
|
11
11
|
# get related_objects from eager_loadings associated with object and associations
|
12
12
|
# get call_object_association from associations of call_object_associations whose object is in related_objects
|
13
|
-
# if association not in call_object_association, then the object => association - call_object_association is ununsed preload
|
13
|
+
# if association not in call_object_association, then the object => association - call_object_association is ununsed preload associations
|
14
14
|
def check_unused_preload_associations
|
15
15
|
return unless Bullet.start?
|
16
16
|
return unless Bullet.unused_eager_loading_enable?
|
@@ -65,7 +65,7 @@ module Bullet
|
|
65
65
|
private
|
66
66
|
|
67
67
|
def create_notification(callers, klazz, associations)
|
68
|
-
notify_associations = Array(associations) - Bullet.get_safelist_associations(:unused_eager_loading, klazz)
|
68
|
+
notify_associations = Array.wrap(associations) - Bullet.get_safelist_associations(:unused_eager_loading, klazz)
|
69
69
|
|
70
70
|
if notify_associations.present?
|
71
71
|
notice = Bullet::Notification::UnusedEagerLoading.new(callers, klazz, notify_associations)
|
data/lib/bullet/rack.rb
CHANGED
@@ -42,6 +42,7 @@ module Bullet
|
|
42
42
|
def empty?(response)
|
43
43
|
# response may be ["Not Found"], ["Move Permanently"], etc, but
|
44
44
|
# those should not happen if the status is 200
|
45
|
+
return true if !response.respond_to?(:body) && !response.respond_to?(:first)
|
45
46
|
body = response_body(response)
|
46
47
|
body.nil? || body.empty?
|
47
48
|
end
|
@@ -78,7 +79,7 @@ module Bullet
|
|
78
79
|
end
|
79
80
|
|
80
81
|
def html_request?(headers, response)
|
81
|
-
headers['Content-Type']&.include?('text/html')
|
82
|
+
headers['Content-Type']&.include?('text/html')
|
82
83
|
end
|
83
84
|
|
84
85
|
def response_body(response)
|
data/lib/bullet/version.rb
CHANGED
data/lib/bullet.rb
CHANGED
@@ -109,7 +109,7 @@ module Bullet
|
|
109
109
|
end
|
110
110
|
|
111
111
|
def get_safelist_associations(type, class_name)
|
112
|
-
Array(@safelist[type][class_name])
|
112
|
+
Array.wrap(@safelist[type][class_name])
|
113
113
|
end
|
114
114
|
|
115
115
|
def reset_safelist
|
@@ -120,51 +120,6 @@ module Bullet
|
|
120
120
|
@safelist = nil
|
121
121
|
end
|
122
122
|
|
123
|
-
def add_whitelist(options)
|
124
|
-
ActiveSupport::Deprecation.warn(<<~WARN.strip
|
125
|
-
add_whitelist is deprecated in favor of add_safelist. It will be removed from the next major release.
|
126
|
-
WARN
|
127
|
-
)
|
128
|
-
|
129
|
-
add_safelist(options)
|
130
|
-
end
|
131
|
-
|
132
|
-
def delete_whitelist(options)
|
133
|
-
ActiveSupport::Deprecation.warn(<<~WARN.strip
|
134
|
-
delete_whitelist is deprecated in favor of delete_safelist. It will be removed from the next major release.
|
135
|
-
WARN
|
136
|
-
)
|
137
|
-
|
138
|
-
delete_safelist(options)
|
139
|
-
end
|
140
|
-
|
141
|
-
def get_whitelist_associations(type, class_name)
|
142
|
-
ActiveSupport::Deprecation.warn(<<~WARN.strip
|
143
|
-
get_whitelist_associations is deprecated in favor of get_safelist_associations. It will be removed from the next major release.
|
144
|
-
WARN
|
145
|
-
)
|
146
|
-
|
147
|
-
get_safelist_associations(type, class_name)
|
148
|
-
end
|
149
|
-
|
150
|
-
def reset_whitelist
|
151
|
-
ActiveSupport::Deprecation.warn(<<~WARN.strip
|
152
|
-
reset_whitelist is deprecated in favor of reset_safelist. It will be removed from the next major release.
|
153
|
-
WARN
|
154
|
-
)
|
155
|
-
|
156
|
-
reset_safelist
|
157
|
-
end
|
158
|
-
|
159
|
-
def clear_whitelist
|
160
|
-
ActiveSupport::Deprecation.warn(<<~WARN.strip
|
161
|
-
clear_whitelist is deprecated in favor of clear_safelist. It will be removed from the next major release.
|
162
|
-
WARN
|
163
|
-
)
|
164
|
-
|
165
|
-
clear_safelist
|
166
|
-
end
|
167
|
-
|
168
123
|
def bullet_logger=(active)
|
169
124
|
if active
|
170
125
|
require 'fileutils'
|
@@ -39,7 +39,7 @@ module Bullet
|
|
39
39
|
|
40
40
|
it 'should be false if object, association pair is not existed' do
|
41
41
|
NPlusOneQuery.add_object_associations(@post, :association1)
|
42
|
-
expect(NPlusOneQuery.association?(@post, :
|
42
|
+
expect(NPlusOneQuery.association?(@post, :association2)).to eq false
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
@@ -74,8 +74,8 @@ module Bullet
|
|
74
74
|
it 'should send full_notice to notifier' do
|
75
75
|
notifier = double
|
76
76
|
allow(subject).to receive(:notifier).and_return(notifier)
|
77
|
-
allow(subject).to receive(:notification_data).and_return(foo: :bar)
|
78
|
-
expect(notifier).to receive(:inline_notify).with(foo: :bar)
|
77
|
+
allow(subject).to receive(:notification_data).and_return({ foo: :bar })
|
78
|
+
expect(notifier).to receive(:inline_notify).with({ foo: :bar })
|
79
79
|
subject.notify_inline
|
80
80
|
end
|
81
81
|
end
|
@@ -84,8 +84,8 @@ module Bullet
|
|
84
84
|
it 'should send full_out_of_channel to notifier' do
|
85
85
|
notifier = double
|
86
86
|
allow(subject).to receive(:notifier).and_return(notifier)
|
87
|
-
allow(subject).to receive(:notification_data).and_return(foo: :bar)
|
88
|
-
expect(notifier).to receive(:out_of_channel_notify).with(foo: :bar)
|
87
|
+
allow(subject).to receive(:notification_data).and_return({ foo: :bar })
|
88
|
+
expect(notifier).to receive(:out_of_channel_notify).with({ foo: :bar })
|
89
89
|
subject.notify_out_of_channel
|
90
90
|
end
|
91
91
|
end
|
data/spec/bullet/rack_spec.rb
CHANGED
@@ -31,12 +31,6 @@ module Bullet
|
|
31
31
|
response = double(body: '<html><head></head><body></body></html>')
|
32
32
|
expect(middleware).not_to be_html_request(headers, response)
|
33
33
|
end
|
34
|
-
|
35
|
-
it "should be false if response body doesn't contain html tag" do
|
36
|
-
headers = { 'Content-Type' => 'text/html' }
|
37
|
-
response = double(body: '<div>Partial</div>')
|
38
|
-
expect(middleware).not_to be_html_request(headers, response)
|
39
|
-
end
|
40
34
|
end
|
41
35
|
|
42
36
|
context 'empty?' do
|
@@ -54,6 +48,11 @@ module Bullet
|
|
54
48
|
response = double(body: '')
|
55
49
|
expect(middleware).to be_empty(response)
|
56
50
|
end
|
51
|
+
|
52
|
+
it 'should be true if no response body' do
|
53
|
+
response = double()
|
54
|
+
expect(middleware).to be_empty(response)
|
55
|
+
end
|
57
56
|
end
|
58
57
|
|
59
58
|
context '#call' do
|
data/spec/bullet_spec.rb
CHANGED
@@ -83,15 +83,6 @@ describe Bullet, focused: true do
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
-
describe '#add_whitelist' do
|
87
|
-
context "for 'special' class names" do
|
88
|
-
it 'is added to the safelist successfully' do
|
89
|
-
Bullet.add_whitelist(type: :n_plus_one_query, class_name: 'Klass', association: :department)
|
90
|
-
expect(Bullet.get_safelist_associations(:n_plus_one_query, 'Klass')).to include :department
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
86
|
describe '#delete_safelist' do
|
96
87
|
context "for 'special' class names" do
|
97
88
|
it 'is deleted from the safelist successfully' do
|
@@ -112,26 +103,6 @@ describe Bullet, focused: true do
|
|
112
103
|
end
|
113
104
|
end
|
114
105
|
|
115
|
-
describe '#delete_whitelist' do
|
116
|
-
context "for 'special' class names" do
|
117
|
-
it 'is deleted from the safelist successfully' do
|
118
|
-
Bullet.add_safelist(type: :n_plus_one_query, class_name: 'Klass', association: :department)
|
119
|
-
Bullet.delete_whitelist(type: :n_plus_one_query, class_name: 'Klass', association: :department)
|
120
|
-
expect(Bullet.safelist[:n_plus_one_query]).to eq({})
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
context 'when exists multiple definitions' do
|
125
|
-
it 'is deleted from the safelist successfully' do
|
126
|
-
Bullet.add_safelist(type: :n_plus_one_query, class_name: 'Klass', association: :department)
|
127
|
-
Bullet.add_safelist(type: :n_plus_one_query, class_name: 'Klass', association: :team)
|
128
|
-
Bullet.delete_whitelist(type: :n_plus_one_query, class_name: 'Klass', association: :team)
|
129
|
-
expect(Bullet.get_safelist_associations(:n_plus_one_query, 'Klass')).to include :department
|
130
|
-
expect(Bullet.get_safelist_associations(:n_plus_one_query, 'Klass')).to_not include :team
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
106
|
describe '#perform_out_of_channel_notifications' do
|
136
107
|
let(:notification) { double }
|
137
108
|
|
@@ -451,6 +451,16 @@ if active_record?
|
|
451
451
|
expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Student, :teachers)
|
452
452
|
end
|
453
453
|
end
|
454
|
+
|
455
|
+
context 'user => roles' do
|
456
|
+
it 'should detect preload associations' do
|
457
|
+
User.first.roles.includes(:resource).each { |role| role.resource }
|
458
|
+
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
459
|
+
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
460
|
+
|
461
|
+
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
462
|
+
end
|
463
|
+
end
|
454
464
|
end
|
455
465
|
|
456
466
|
describe Bullet::Detector::Association, 'has_many :through' do
|
data/spec/models/role.rb
ADDED
data/spec/models/user.rb
CHANGED
data/spec/support/sqlite_seed.rb
CHANGED
@@ -92,9 +92,16 @@ module Support
|
|
92
92
|
page3 = Page.create(name: 'page3', parent_id: folder2.id, author_id: author2.id)
|
93
93
|
page4 = Page.create(name: 'page4', parent_id: folder2.id, author_id: author2.id)
|
94
94
|
|
95
|
+
role1 = Role.create(name: 'Admin')
|
96
|
+
role2 = Role.create(name: 'User')
|
97
|
+
|
95
98
|
user1 = User.create(name: 'user1', category: category1)
|
96
99
|
user2 = User.create(name: 'user2', category: category1)
|
97
100
|
|
101
|
+
user1.roles << role1
|
102
|
+
user1.roles << role2
|
103
|
+
user2.roles << role2
|
104
|
+
|
98
105
|
submission1 = user1.create_submission(name: 'submission1')
|
99
106
|
submission2 = user2.create_submission(name: 'submission2')
|
100
107
|
|
@@ -246,6 +253,17 @@ module Support
|
|
246
253
|
t.column :submission_id, :integer
|
247
254
|
end
|
248
255
|
|
256
|
+
create_table :roles do |t|
|
257
|
+
t.column :name, :string
|
258
|
+
t.column :resource_id, :integer
|
259
|
+
t.column :resource_type, :string
|
260
|
+
end
|
261
|
+
|
262
|
+
create_table :roles_users do |t|
|
263
|
+
t.column :role_id, :integer
|
264
|
+
t.column :user_id, :integer
|
265
|
+
end
|
266
|
+
|
249
267
|
create_table :submissions do |t|
|
250
268
|
t.column :name, :string
|
251
269
|
t.column :user_id, :integer
|
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: 7.0.
|
4
|
+
version: 7.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Richard Huang
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-08-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -160,6 +160,7 @@ files:
|
|
160
160
|
- spec/models/post.rb
|
161
161
|
- spec/models/relationship.rb
|
162
162
|
- spec/models/reply.rb
|
163
|
+
- spec/models/role.rb
|
163
164
|
- spec/models/student.rb
|
164
165
|
- spec/models/submission.rb
|
165
166
|
- spec/models/teacher.rb
|
@@ -194,7 +195,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
194
195
|
- !ruby/object:Gem::Version
|
195
196
|
version: 1.3.6
|
196
197
|
requirements: []
|
197
|
-
rubygems_version: 3.
|
198
|
+
rubygems_version: 3.3.7
|
198
199
|
signing_key:
|
199
200
|
specification_version: 4
|
200
201
|
summary: help to kill N+1 queries and unused eager loading.
|
@@ -249,6 +250,7 @@ test_files:
|
|
249
250
|
- spec/models/post.rb
|
250
251
|
- spec/models/relationship.rb
|
251
252
|
- spec/models/reply.rb
|
253
|
+
- spec/models/role.rb
|
252
254
|
- spec/models/student.rb
|
253
255
|
- spec/models/submission.rb
|
254
256
|
- spec/models/teacher.rb
|