bullet 5.4.0 → 5.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 58f4f616944a1bfde9a34e4670788802f0ccd418
4
- data.tar.gz: 61aabed03705063018b28e1505f0f0b693e1109b
3
+ metadata.gz: 7f8cac0418ea4a1bb9f8abc6c12e84022f2f118d
4
+ data.tar.gz: ebdf99115037dec22a5480a63d3bed5f15956dda
5
5
  SHA512:
6
- metadata.gz: 4be86c6d80b67bec48ee84d491b3b92cd19f9b9ea6d6d9d7d973848f93801edf0165f9a7f8f9309d7feee84ed2da1d6f39170161da2d0b01fe8debf7724d6dc9
7
- data.tar.gz: b82c8e8207775a8e987e52fbbddb6d35350c591df288e1152ee2d55e8de9f257ca55f82bcac02c59807b3cffa76038c0373fc09ba42c36a45be059fc05fed7e8
6
+ metadata.gz: 0904f996964a403a495af310bab8a0612e614eb72a71d08646948508c25d4bf36d2b939da65156a5fc81595477820e0f123aa2a88d618fe97e28e81a6b6f8ada
7
+ data.tar.gz: d491e12ccce38a26a5e3d27d3f6b84acafe34bb7b6aff56b78a8e22a73a5a3abf88443110587de0080e50b32ef70d8ca387eab5faac0b1bec16efed04bf3acc1
data/.gitignore CHANGED
@@ -12,3 +12,4 @@ benchmark_profile*
12
12
  coverage/
13
13
  .coveralls.yml
14
14
  Gemfile*.lock
15
+ .idea/
data/.travis.yml CHANGED
@@ -1,107 +1,16 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 1.9.3
5
- - 2.0
6
- - 2.1
7
- - 2.2
8
4
  - 2.3.0
9
5
  gemfile:
10
6
  - Gemfile.rails-5.0
11
7
  - Gemfile.rails-4.2
12
8
  - Gemfile.rails-4.1
13
9
  - Gemfile.rails-4.0
14
- - Gemfile.rails-3.2
15
- - Gemfile.rails-3.1
16
- - Gemfile.rails-3.0
10
+ - Gemfile.mongoid-6.0
17
11
  - Gemfile.mongoid-5.0
18
12
  - Gemfile.mongoid-4.0
19
- - Gemfile.mongoid-3.1
20
- - Gemfile.mongoid-3.0
21
- - Gemfile.mongoid-2.8
22
- - Gemfile.mongoid-2.7
23
- - Gemfile.mongoid-2.6
24
- - Gemfile.mongoid-2.5
25
- - Gemfile.mongoid-2.4
26
13
  env:
27
14
  - DB=sqlite
28
15
  services:
29
16
  - mongodb
30
- matrix:
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
60
- - rvm: 2.0
61
- gemfile: Gemfile.rails-5.0
62
- - rvm: 2.1
63
- gemfile: Gemfile.rails-3.0
64
- - rvm: 2.1
65
- gemfile: Gemfile.rails-5.0
66
- - rvm: 2.2
67
- gemfile: Gemfile.rails-3.0
68
- - rvm: 2.2
69
- gemfile: Gemfile.rails-3.1
70
- - rvm: 2.2
71
- gemfile: Gemfile.rails-3.2
72
- - rvm: 2.2
73
- gemfile: Gemfile.rails-5.0
74
- - rvm: 2.2
75
- gemfile: Gemfile.mongoid-3.1
76
- - rvm: 2.2
77
- gemfile: Gemfile.mongoid-3.0
78
- - rvm: 2.2
79
- gemfile: Gemfile.mongoid-2.8
80
- - rvm: 2.2
81
- gemfile: Gemfile.mongoid-2.7
82
- - rvm: 2.2
83
- gemfile: Gemfile.mongoid-2.6
84
- - rvm: 2.2
85
- gemfile: Gemfile.mongoid-2.5
86
- - rvm: 2.2
87
- gemfile: Gemfile.mongoid-2.4
88
- - rvm: 2.3.0
89
- gemfile: Gemfile.rails-3.0
90
- - rvm: 2.3.0
91
- gemfile: Gemfile.rails-3.1
92
- - rvm: 2.3.0
93
- gemfile: Gemfile.rails-3.2
94
- - rvm: 2.3.0
95
- gemfile: Gemfile.mongoid-3.1
96
- - rvm: 2.3.0
97
- gemfile: Gemfile.mongoid-3.0
98
- - rvm: 2.3.0
99
- gemfile: Gemfile.mongoid-2.8
100
- - rvm: 2.3.0
101
- gemfile: Gemfile.mongoid-2.7
102
- - rvm: 2.3.0
103
- gemfile: Gemfile.mongoid-2.6
104
- - rvm: 2.3.0
105
- gemfile: Gemfile.mongoid-2.5
106
- - rvm: 2.3.0
107
- gemfile: Gemfile.mongoid-2.4
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Next Release
2
2
 
3
+ ## 5.5.0 (12/30/2016)
4
+
5
+ * Display http request method #311
6
+ * Add close button to footer
7
+ * Raise an error if bullet does not support AR or Mongoid
8
+ * Avoid double backtrace
9
+ * Fix false alert on counter cache when associations are already loaded #288
10
+ * Fix "false alert" in rails 5 #239
11
+ * Do not support ActiveRecord 3.x and Mongoid 3.x / 4.x anymore
12
+
3
13
  ## 5.4.0 (10/09/2016)
4
14
 
5
15
  * Support rails 5.1
data/Gemfile.mongoid-5.0 CHANGED
@@ -5,7 +5,7 @@ gemspec
5
5
  gem 'rails', '~> 4.0.0'
6
6
  gem 'sqlite3', platforms: [:ruby]
7
7
  gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
- gem 'mongoid', '~> 5.0.0'
8
+ gem 'mongoid', '~> 5.1.0'
9
9
 
10
10
  gem "rspec"
11
11
 
@@ -2,10 +2,10 @@ source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'rails', '~> 3.2.0'
5
+ gem 'rails', '~> 5.0.0'
6
6
  gem 'sqlite3', platforms: [:ruby]
7
7
  gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
- gem 'mongoid', '~> 2.4.0'
8
+ gem 'mongoid', '~> 6.0.0'
9
9
 
10
10
  gem "rspec"
11
11
 
data/README.md CHANGED
@@ -9,10 +9,12 @@ The Bullet gem is designed to help you increase your application's performance b
9
9
 
10
10
  Best practice is to use Bullet in development mode or custom mode (staging, profile, etc.). The last thing you want is your clients getting alerts about how lazy you are.
11
11
 
12
- Bullet gem now supports **activerecord** >= 3.0 and **mongoid** >= 2.4.1.
12
+ Bullet gem now supports **activerecord** >= 4.0 and **mongoid** >= 4.0.
13
13
 
14
14
  If you use activerecord 2.x, please use bullet <= 4.5.0
15
15
 
16
+ If you use activerecord 3.x, plesae use bullet < 5.5.0
17
+
16
18
  ## External Introduction
17
19
 
18
20
  * [http://railscasts.com/episodes/372-bullet](http://railscasts.com/episodes/372-bullet)
@@ -81,7 +83,7 @@ The code above will enable all seven of the Bullet notification systems:
81
83
  * `Bullet.growl`: pop up Growl warnings if your system has Growl installed. Requires a little bit of configuration
82
84
  * `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.
83
85
  * `Bullet.raise`: raise errors, useful for making your specs fail unless they have optimized queries
84
- * `Bullet.add_footer`: adds the details in the bottom left corner of the page
86
+ * `Bullet.add_footer`: adds the details in the bottom left corner of the page. Double click the footer or use close button to hide footer.
85
87
  * `Bullet.stacktrace_includes`: include paths with any of these substrings in the stack trace, even if they are not in your main app
86
88
  * `Bullet.stacktrace_excludes`: ignore paths with any of these substrings in the stack trace, even if they are not in your main app.
87
89
  * `Bullet.slack`: add notifications to slack
@@ -332,7 +334,7 @@ model: Post => associations: [comment]
332
334
 
333
335
  which means there is a N+1 query from the Post object to its Comment association.
334
336
 
335
- In the meanwhile, there's a log appended into `log/bullet.log` file
337
+ In the meantime, there's a log appended into `log/bullet.log` file
336
338
 
337
339
  ```
338
340
  2010-03-07 14:12:18[INFO] N+1 Query in /posts
@@ -9,8 +9,13 @@ module Bullet
9
9
  result = origin_find_by_sql(sql, binds)
10
10
  if Bullet.start?
11
11
  if result.is_a? Array
12
- Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
13
- Bullet::Detector::CounterCache.add_possible_objects(result)
12
+ if result.size > 1
13
+ Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
14
+ Bullet::Detector::CounterCache.add_possible_objects(result)
15
+ elsif result.size == 1
16
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(result.first)
17
+ Bullet::Detector::CounterCache.add_impossible_object(result.first)
18
+ end
14
19
  elsif result.is_a? ::ActiveRecord::Base
15
20
  Bullet::Detector::NPlusOneQuery.add_impossible_object(result)
16
21
  Bullet::Detector::CounterCache.add_impossible_object(result)
@@ -147,7 +152,7 @@ module Bullet
147
152
  ::ActiveRecord::Associations::HasManyAssociation.class_eval do
148
153
  alias_method :origin_empty?, :empty?
149
154
  def empty?
150
- if Bullet.start? && !has_cached_counter?(@reflection)
155
+ if Bullet.start? && !loaded? && !has_cached_counter?(@reflection)
151
156
  Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
152
157
  end
153
158
  origin_empty?
@@ -157,7 +162,7 @@ module Bullet
157
162
  ::ActiveRecord::Associations::HasAndBelongsToManyAssociation.class_eval do
158
163
  alias_method :origin_empty?, :empty?
159
164
  def empty?
160
- if Bullet.start?
165
+ if Bullet.start? && !loaded?
161
166
  Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
162
167
  end
163
168
  origin_empty?
@@ -9,8 +9,13 @@ module Bullet
9
9
  result = origin_find_by_sql(sql, binds)
10
10
  if Bullet.start?
11
11
  if result.is_a? Array
12
- Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
13
- Bullet::Detector::CounterCache.add_possible_objects(result)
12
+ if result.size > 1
13
+ Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
14
+ Bullet::Detector::CounterCache.add_possible_objects(result)
15
+ elsif result.size == 1
16
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(result.first)
17
+ Bullet::Detector::CounterCache.add_impossible_object(result.first)
18
+ end
14
19
  elsif result.is_a? ::ActiveRecord::Base
15
20
  Bullet::Detector::NPlusOneQuery.add_impossible_object(result)
16
21
  Bullet::Detector::CounterCache.add_impossible_object(result)
@@ -171,14 +176,13 @@ module Bullet
171
176
  end
172
177
 
173
178
  ::ActiveRecord::Associations::HasManyAssociation.class_eval do
174
- alias_method :origin_has_cached_counter?, :has_cached_counter?
175
-
176
- def has_cached_counter?(reflection = reflection())
177
- result = origin_has_cached_counter?(reflection)
179
+ alias_method :origin_count_records, :count_records
180
+ def count_records
181
+ result = has_cached_counter?
178
182
  if Bullet.start? && !result
179
- Bullet::Detector::CounterCache.add_counter_cache(owner, reflection.name)
183
+ Bullet::Detector::CounterCache.add_counter_cache(@owner, @reflection.name)
180
184
  end
181
- result
185
+ origin_count_records
182
186
  end
183
187
  end
184
188
  end
@@ -24,8 +24,13 @@ module Bullet
24
24
  result = origin_find_by_sql(sql, binds)
25
25
  if Bullet.start?
26
26
  if result.is_a? Array
27
- Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
28
- Bullet::Detector::CounterCache.add_possible_objects(result)
27
+ if result.size > 1
28
+ Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
29
+ Bullet::Detector::CounterCache.add_possible_objects(result)
30
+ elsif result.size == 1
31
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(result.first)
32
+ Bullet::Detector::CounterCache.add_impossible_object(result.first)
33
+ end
29
34
  elsif result.is_a? ::ActiveRecord::Base
30
35
  Bullet::Detector::NPlusOneQuery.add_impossible_object(result)
31
36
  Bullet::Detector::CounterCache.add_impossible_object(result)
@@ -225,33 +230,20 @@ module Bullet
225
230
  ::ActiveRecord::Associations::HasManyAssociation.class_eval do
226
231
  alias_method :origin_many_empty?, :empty?
227
232
  def empty?
228
- Thread.current[:bullet_collection_empty] = true
229
233
  result = origin_many_empty?
230
- Thread.current[:bullet_collection_empty] = nil
231
234
  if Bullet.start? && !has_cached_counter?(@reflection)
232
235
  Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
233
236
  end
234
237
  result
235
238
  end
236
239
 
237
- alias_method :origin_has_cached_counter?, :has_cached_counter?
238
- def has_cached_counter?(reflection = reflection())
239
- result = origin_has_cached_counter?(reflection)
240
- if Bullet.start? && !result && !Thread.current[:bullet_collection_empty]
241
- Bullet::Detector::CounterCache.add_counter_cache(owner, reflection.name)
240
+ alias_method :origin_count_records, :count_records
241
+ def count_records
242
+ result = has_cached_counter?
243
+ if Bullet.start? && !result
244
+ Bullet::Detector::CounterCache.add_counter_cache(@owner, @reflection.name)
242
245
  end
243
- result
244
- end
245
- end
246
-
247
- ::ActiveRecord::Associations::HasManyThroughAssociation.class_eval do
248
- alias_method :origin_hmt_has_cached_counter?, :has_cached_counter?
249
- def has_cached_counter?(reflection = reflection())
250
- result = origin_hmt_has_cached_counter?(reflection)
251
- if Bullet.start? && !result && !Thread.current[:bullet_collection_empty]
252
- Bullet::Detector::CounterCache.add_counter_cache(owner, reflection.name)
253
- end
254
- result
246
+ origin_count_records
255
247
  end
256
248
  end
257
249
  end
@@ -25,8 +25,13 @@ module Bullet
25
25
  result = origin_find_by_sql(sql, binds, preparable: nil)
26
26
  if Bullet.start?
27
27
  if result.is_a? Array
28
- Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
29
- Bullet::Detector::CounterCache.add_possible_objects(result)
28
+ if result.size > 1
29
+ Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
30
+ Bullet::Detector::CounterCache.add_possible_objects(result)
31
+ elsif result.size == 1
32
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(result.first)
33
+ Bullet::Detector::CounterCache.add_impossible_object(result.first)
34
+ end
30
35
  elsif result.is_a? ::ActiveRecord::Base
31
36
  Bullet::Detector::NPlusOneQuery.add_impossible_object(result)
32
37
  Bullet::Detector::CounterCache.add_impossible_object(result)
@@ -14,11 +14,7 @@ module Bullet
14
14
 
15
15
  def active_record_version
16
16
  @active_record_version ||= begin
17
- if active_record30?
18
- 'active_record3'
19
- elsif active_record31? || active_record32?
20
- 'active_record3x'
21
- elsif active_record40?
17
+ if active_record40?
22
18
  'active_record4'
23
19
  elsif active_record41?
24
20
  'active_record41'
@@ -28,28 +24,26 @@ module Bullet
28
24
  'active_record5'
29
25
  elsif active_record51?
30
26
  'active_record5'
27
+ else
28
+ raise "Bullet does not support active_record #{::ActiveRecord::VERSION} yet"
31
29
  end
32
30
  end
33
31
  end
34
32
 
35
33
  def mongoid_version
36
34
  @mongoid_version ||= begin
37
- if mongoid2x?
38
- 'mongoid2x'
39
- elsif mongoid3x?
40
- 'mongoid3x'
41
- elsif mongoid4x?
35
+ if mongoid4x?
42
36
  'mongoid4x'
43
37
  elsif mongoid5x?
44
38
  'mongoid5x'
39
+ elsif mongoid6x?
40
+ 'mongoid6x'
41
+ else
42
+ raise "Bullet does not support mongoid #{::Mongoid::VERSION} yet"
45
43
  end
46
44
  end
47
45
  end
48
46
 
49
- def active_record3?
50
- active_record? && ::ActiveRecord::VERSION::MAJOR == 3
51
- end
52
-
53
47
  def active_record4?
54
48
  active_record? && ::ActiveRecord::VERSION::MAJOR == 4
55
49
  end
@@ -58,18 +52,6 @@ module Bullet
58
52
  active_record? && ::ActiveRecord::VERSION::MAJOR == 5
59
53
  end
60
54
 
61
- def active_record30?
62
- active_record3? && ::ActiveRecord::VERSION::MINOR == 0
63
- end
64
-
65
- def active_record31?
66
- active_record3? && ::ActiveRecord::VERSION::MINOR == 1
67
- end
68
-
69
- def active_record32?
70
- active_record3? && ::ActiveRecord::VERSION::MINOR == 2
71
- end
72
-
73
55
  def active_record40?
74
56
  active_record4? && ::ActiveRecord::VERSION::MINOR == 0
75
57
  end
@@ -90,14 +72,6 @@ module Bullet
90
72
  active_record5? && ::ActiveRecord::VERSION::MINOR == 1
91
73
  end
92
74
 
93
- def mongoid2x?
94
- mongoid? && ::Mongoid::VERSION =~ /\A2\.[4-9]/
95
- end
96
-
97
- def mongoid3x?
98
- mongoid? && ::Mongoid::VERSION =~ /\A3/
99
- end
100
-
101
75
  def mongoid4x?
102
76
  mongoid? && ::Mongoid::VERSION =~ /\A4/
103
77
  end
@@ -105,5 +79,9 @@ module Bullet
105
79
  def mongoid5x?
106
80
  mongoid? && ::Mongoid::VERSION =~ /\A5/
107
81
  end
82
+
83
+ def mongoid6x?
84
+ mongoid? && ::Mongoid::VERSION =~ /\A6/
85
+ end
108
86
  end
109
87
  end
@@ -21,7 +21,7 @@ module Bullet
21
21
  end
22
22
 
23
23
  def each(&block)
24
- records = query.map{ |doc| ::Mongoid::Factory.from_db(klass, doc) }
24
+ records = view.map{ |doc| ::Mongoid::Factory.from_db(klass, doc) }
25
25
  if records.length > 1
26
26
  Bullet::Detector::NPlusOneQuery.add_possible_objects(records)
27
27
  elsif records.size == 1
@@ -43,8 +43,8 @@ module Bullet
43
43
  ::Mongoid::Relations::Accessors.class_eval do
44
44
  alias_method :origin_get_relation, :get_relation
45
45
 
46
- def get_relation(name, metadata, reload = false)
47
- result = origin_get_relation(name, metadata, reload)
46
+ def get_relation(name, metadata, object, reload = false)
47
+ result = origin_get_relation(name, metadata, object, reload)
48
48
  if metadata.macro !~ /embed/
49
49
  Bullet::Detector::NPlusOneQuery.call_association(self, name)
50
50
  end
@@ -12,18 +12,18 @@ module Bullet
12
12
  end
13
13
 
14
14
  def title
15
- "N+1 Query #{@path ? "in #{@path}" : 'detected'}"
15
+ "USE eager loading #{@path ? "in #{@path}" : 'detected'}"
16
16
  end
17
17
 
18
18
  def notification_data
19
19
  super.merge(
20
- :backtrace => @callers
20
+ :backtrace => []
21
21
  )
22
22
  end
23
23
 
24
24
  protected
25
25
  def call_stack_messages
26
- (['N+1 Query method call stack'] + @callers).join( "\n " )
26
+ (['Call stack'] + @callers).join( "\n " )
27
27
  end
28
28
  end
29
29
  end
@@ -7,19 +7,24 @@ module Bullet
7
7
  @callers = callers
8
8
  end
9
9
 
10
- def notification_data
11
- super.merge(
12
- :backtrace => @callers
13
- )
14
- end
15
-
16
10
  def body
17
11
  "#{klazz_associations_str}\n Remove from your finder: #{associations_str}"
18
12
  end
19
13
 
20
14
  def title
21
- "Unused Eager Loading #{@path ? "in #{@path}" : 'detected'}"
15
+ "AVOID eager loading #{@path ? "in #{@path}" : 'detected'}"
22
16
  end
17
+
18
+ def notification_data
19
+ super.merge(
20
+ :backtrace => []
21
+ )
22
+ end
23
+
24
+ protected
25
+ def call_stack_messages
26
+ (['Call stack'] + @callers).join( "\n " )
27
+ end
23
28
  end
24
29
  end
25
30
  end
data/lib/bullet/rack.rb CHANGED
@@ -51,7 +51,7 @@ module Bullet
51
51
  end
52
52
 
53
53
  def footer_note
54
- "<div #{footer_div_attributes}>" + Bullet.footer_info.uniq.join("<br>") + "</div>"
54
+ "<div #{footer_div_attributes}>" + footer_close_button + Bullet.footer_info.uniq.join("<br>") + "</div>"
55
55
  end
56
56
 
57
57
  def file?(headers)
@@ -75,6 +75,7 @@ module Bullet
75
75
  end
76
76
 
77
77
  private
78
+
78
79
  def footer_div_attributes
79
80
  <<EOF
80
81
  data-is-bullet-footer ondblclick="this.parentNode.removeChild(this);" style="position: fixed; bottom: 0pt; left: 0pt; cursor: pointer; border-style: solid; border-color: rgb(153, 153, 153);
@@ -84,5 +85,9 @@ data-is-bullet-footer ondblclick="this.parentNode.removeChild(this);" style="pos
84
85
  color: rgb(119, 119, 119); font-size: 16px; font-family: 'Arial', sans-serif; z-index:9999;"
85
86
  EOF
86
87
  end
88
+
89
+ def footer_close_button
90
+ "<span onclick='this.parentNode.remove()' style='position:absolute; right: 10px; top: 0px; font-weight: bold; color: #333;'>&times;</span>"
91
+ end
87
92
  end
88
93
  end
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module Bullet
3
- VERSION = "5.4.0"
3
+ VERSION = "5.5.0"
4
4
  end
data/lib/bullet.rb CHANGED
@@ -167,7 +167,7 @@ module Bullet
167
167
  end
168
168
 
169
169
  def perform_out_of_channel_notifications(env = {})
170
- request_uri = env['REQUEST_URI'] || build_request_uri(env)
170
+ request_uri = build_request_uri(env)
171
171
  for_each_active_notifier_with_notification do |notification|
172
172
  notification.url = request_uri
173
173
  notification.notify_out_of_channel
@@ -221,10 +221,12 @@ module Bullet
221
221
  end
222
222
 
223
223
  def build_request_uri(env)
224
+ return "#{env['REQUEST_METHOD']} #{env['REQUEST_URI']}" if env['REQUEST_URI']
225
+
224
226
  if env['QUERY_STRING'].present?
225
- "#{env['PATH_INFO']}?#{env['QUERY_STRING']}"
227
+ "#{env['REQUEST_METHOD']} #{env['PATH_INFO']}?#{env['QUERY_STRING']}"
226
228
  else
227
- env['PATH_INFO']
229
+ "#{env['REQUEST_METHOD']} #{env['PATH_INFO']}"
228
230
  end
229
231
  end
230
232
  end
@@ -5,10 +5,10 @@ module Bullet
5
5
  describe NPlusOneQuery do
6
6
  subject { NPlusOneQuery.new([["caller1", "caller2"]], Post, [:comments, :votes], "path") }
7
7
 
8
- it { expect(subject.body_with_caller).to eq(" Post => [:comments, :votes]\n Add to your finder: :includes => [:comments, :votes]\nN+1 Query method call stack\n caller1\n caller2\n") }
9
- it { expect([subject.body_with_caller, subject.body_with_caller]).to eq([ " Post => [:comments, :votes]\n Add to your finder: :includes => [:comments, :votes]\nN+1 Query method call stack\n caller1\n caller2\n", " Post => [:comments, :votes]\n Add to your finder: :includes => [:comments, :votes]\nN+1 Query method call stack\n caller1\n caller2\n" ]) }
8
+ it { expect(subject.body_with_caller).to eq(" Post => [:comments, :votes]\n Add to your finder: :includes => [:comments, :votes]\nCall stack\n caller1\n caller2\n") }
9
+ it { expect([subject.body_with_caller, subject.body_with_caller]).to eq([ " Post => [:comments, :votes]\n Add to your finder: :includes => [:comments, :votes]\nCall stack\n caller1\n caller2\n", " Post => [:comments, :votes]\n Add to your finder: :includes => [:comments, :votes]\nCall stack\n caller1\n caller2\n" ]) }
10
10
  it { expect(subject.body).to eq(" Post => [:comments, :votes]\n Add to your finder: :includes => [:comments, :votes]") }
11
- it { expect(subject.title).to eq("N+1 Query in path") }
11
+ it { expect(subject.title).to eq("USE eager loading in path") }
12
12
  end
13
13
  end
14
14
  end
@@ -6,7 +6,7 @@ module Bullet
6
6
  subject { UnusedEagerLoading.new([""], Post, [:comments, :votes], "path") }
7
7
 
8
8
  it { expect(subject.body).to eq(" Post => [:comments, :votes]\n Remove from your finder: :includes => [:comments, :votes]") }
9
- it { expect(subject.title).to eq("Unused Eager Loading in path") }
9
+ it { expect(subject.title).to eq("AVOID eager loading in path") }
10
10
  end
11
11
  end
12
12
  end
data/spec/bullet_spec.rb CHANGED
@@ -103,16 +103,10 @@ describe Bullet, focused: true do
103
103
  allow(notification).to receive(:notify_out_of_channel)
104
104
  end
105
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
106
  context 'when called with Rack environment hash' do
114
107
  let(:env) {
115
108
  {
109
+ 'REQUEST_METHOD' => 'GET',
116
110
  'PATH_INFO' => '/path',
117
111
  'QUERY_STRING' => 'foo=bar',
118
112
  }
@@ -122,7 +116,7 @@ describe Bullet, focused: true do
122
116
  before { env['REQUEST_URI'] = nil }
123
117
 
124
118
  it 'should notification.url is built' do
125
- expect(notification).to receive(:url=).with('/path?foo=bar')
119
+ expect(notification).to receive(:url=).with('GET /path?foo=bar')
126
120
  Bullet.perform_out_of_channel_notifications(env)
127
121
  end
128
122
  end
@@ -131,7 +125,7 @@ describe Bullet, focused: true do
131
125
  before { env['REQUEST_URI'] = 'http://example.com/path' }
132
126
 
133
127
  it "should notification.url is env['REQUEST_URI']" do
134
- expect(notification).to receive(:url=).with(env['REQUEST_URI'])
128
+ expect(notification).to receive(:url=).with('GET http://example.com/path')
135
129
  Bullet.perform_out_of_channel_notifications(env)
136
130
  end
137
131
  end
@@ -29,6 +29,13 @@ if !mongoid? && active_record?
29
29
  expect(Bullet.collected_counter_cache_notifications).to be_empty
30
30
  end
31
31
 
32
+ it "should not need counter cache without size" do
33
+ Country.includes(:cities).each do |country|
34
+ country.cities.empty?
35
+ end
36
+ expect(Bullet.collected_counter_cache_notifications).to be_empty
37
+ end
38
+
32
39
  if active_record5?
33
40
  it "should not need counter cache for has_many through" do
34
41
  Client.all.each do |client|