hyper-pure-sys 0.0.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.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/bullet-8.1.3/CHANGELOG.md +374 -0
  3. data/bullet-8.1.3/MIT-LICENSE +20 -0
  4. data/bullet-8.1.3/README.md +525 -0
  5. data/bullet-8.1.3/lib/bullet/active_job.rb +13 -0
  6. data/bullet-8.1.3/lib/bullet/active_record4.rb +197 -0
  7. data/bullet-8.1.3/lib/bullet/active_record41.rb +191 -0
  8. data/bullet-8.1.3/lib/bullet/active_record42.rb +262 -0
  9. data/bullet-8.1.3/lib/bullet/active_record5.rb +294 -0
  10. data/bullet-8.1.3/lib/bullet/active_record52.rb +278 -0
  11. data/bullet-8.1.3/lib/bullet/active_record60.rb +310 -0
  12. data/bullet-8.1.3/lib/bullet/active_record61.rb +310 -0
  13. data/bullet-8.1.3/lib/bullet/active_record70.rb +319 -0
  14. data/bullet-8.1.3/lib/bullet/active_record71.rb +319 -0
  15. data/bullet-8.1.3/lib/bullet/active_record72.rb +319 -0
  16. data/bullet-8.1.3/lib/bullet/active_record80.rb +319 -0
  17. data/bullet-8.1.3/lib/bullet/active_record81.rb +321 -0
  18. data/bullet-8.1.3/lib/bullet/bullet_xhr.js +64 -0
  19. data/bullet-8.1.3/lib/bullet/dependency.rb +165 -0
  20. data/bullet-8.1.3/lib/bullet/detector/association.rb +92 -0
  21. data/bullet-8.1.3/lib/bullet/detector/base.rb +8 -0
  22. data/bullet-8.1.3/lib/bullet/detector/counter_cache.rb +69 -0
  23. data/bullet-8.1.3/lib/bullet/detector/n_plus_one_query.rb +148 -0
  24. data/bullet-8.1.3/lib/bullet/detector/unused_eager_loading.rb +100 -0
  25. data/bullet-8.1.3/lib/bullet/detector.rb +11 -0
  26. data/bullet-8.1.3/lib/bullet/ext/object.rb +37 -0
  27. data/bullet-8.1.3/lib/bullet/ext/string.rb +14 -0
  28. data/bullet-8.1.3/lib/bullet/mongoid4x.rb +59 -0
  29. data/bullet-8.1.3/lib/bullet/mongoid5x.rb +59 -0
  30. data/bullet-8.1.3/lib/bullet/mongoid6x.rb +59 -0
  31. data/bullet-8.1.3/lib/bullet/mongoid7x.rb +74 -0
  32. data/bullet-8.1.3/lib/bullet/mongoid8x.rb +61 -0
  33. data/bullet-8.1.3/lib/bullet/mongoid9x.rb +74 -0
  34. data/bullet-8.1.3/lib/bullet/notification/base.rb +92 -0
  35. data/bullet-8.1.3/lib/bullet/notification/counter_cache.rb +15 -0
  36. data/bullet-8.1.3/lib/bullet/notification/n_plus_one_query.rb +31 -0
  37. data/bullet-8.1.3/lib/bullet/notification/unused_eager_loading.rb +31 -0
  38. data/bullet-8.1.3/lib/bullet/notification.rb +13 -0
  39. data/bullet-8.1.3/lib/bullet/notification_collector.rb +25 -0
  40. data/bullet-8.1.3/lib/bullet/rack.rb +186 -0
  41. data/bullet-8.1.3/lib/bullet/registry/association.rb +16 -0
  42. data/bullet-8.1.3/lib/bullet/registry/base.rb +46 -0
  43. data/bullet-8.1.3/lib/bullet/registry/call_stack.rb +17 -0
  44. data/bullet-8.1.3/lib/bullet/registry/object.rb +18 -0
  45. data/bullet-8.1.3/lib/bullet/registry.rb +10 -0
  46. data/bullet-8.1.3/lib/bullet/stack_trace_filter.rb +67 -0
  47. data/bullet-8.1.3/lib/bullet/version.rb +5 -0
  48. data/bullet-8.1.3/lib/bullet.rb +289 -0
  49. data/bullet-8.1.3/lib/generators/bullet/install_generator.rb +47 -0
  50. data/bullet-8.1.3/tasks/bullet_tasks.rake +11 -0
  51. data/hyper-pure-sys.gemspec +12 -0
  52. metadata +91 -0
@@ -0,0 +1,525 @@
1
+ # Bullet
2
+
3
+ ![Main workflow](https://github.com/flyerhzm/bullet/actions/workflows/main.yml/badge.svg)
4
+ [![Gem Version](https://badge.fury.io/rb/bullet.svg)](http://badge.fury.io/rb/bullet)
5
+ [![AwesomeCode Status for flyerhzm/bullet](https://awesomecode.io/projects/6755235b-e2c1-459e-bf92-b8b13d0c0472/status)](https://awesomecode.io/repos/flyerhzm/bullet)
6
+ [![Coderwall Endorse](https://coderwall.com/flyerhzm/endorsecount.png)](https://coderwall.com/flyerhzm)
7
+
8
+ The Bullet gem is designed to help you increase your application's performance by reducing the number of queries it makes. It will watch your queries while you develop your application and notify you when you should add eager loading (N+1 queries), when you're using eager loading that isn't necessary and when you should use counter cache.
9
+
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
+
12
+ Bullet gem now supports **activerecord** >= 4.0 and **mongoid** >= 4.0.
13
+
14
+ If you use activerecord 2.x, please use bullet <= 4.5.0
15
+
16
+ If you use activerecord 3.x, please use bullet < 5.5.0
17
+
18
+ ## External Introduction
19
+
20
+ * [https://rubyonrails.org/2009/10/22/community-highlights](https://rubyonrails.org/2009/10/22/community-highlights)
21
+ * [https://www.shakacode.com/blog/eliminate-N-1-queries-with-bullet/](https://www.shakacode.com/blog/eliminate-N-1-queries-with-bullet/)
22
+ * [https://reinteractive.com/articles/ruby-on-rails-community/elevating-your-code-quality-bullet-gem-and-query-prevention-in-testing](https://reinteractive.com/articles/ruby-on-rails-community/elevating-your-code-quality-bullet-gem-and-query-prevention-in-testing)
23
+
24
+ ## Install
25
+
26
+ You can install it as a gem:
27
+
28
+ ```
29
+ gem install bullet
30
+ ```
31
+
32
+ or add it into a Gemfile (Bundler):
33
+
34
+
35
+ ```ruby
36
+ gem 'bullet', group: 'development'
37
+ ```
38
+
39
+ enable the Bullet gem with generate command
40
+
41
+ ```ruby
42
+ bundle exec rails g bullet:install
43
+ ```
44
+ The generate command will auto generate the default configuration and may ask to include in the test environment as well. See below for custom configuration.
45
+
46
+ **Note**: make sure `bullet` gem is added after activerecord (rails) and
47
+ mongoid.
48
+
49
+ ## Configuration
50
+
51
+ Bullet won't enable any notification systems unless you tell it to explicitly. Append to
52
+ `config/environments/development.rb` initializer with the following code:
53
+
54
+ ```ruby
55
+ config.after_initialize do
56
+ Bullet.enable = true
57
+ Bullet.sentry = true
58
+ Bullet.alert = true
59
+ Bullet.bullet_logger = true
60
+ Bullet.console = true
61
+ Bullet.xmpp = { :account => 'bullets_account@jabber.org',
62
+ :password => 'bullets_password_for_jabber',
63
+ :receiver => 'your_account@jabber.org',
64
+ :show_online_status => true }
65
+ Bullet.rails_logger = true
66
+ Bullet.honeybadger = true
67
+ Bullet.bugsnag = true
68
+ Bullet.appsignal = true
69
+ Bullet.airbrake = true
70
+ Bullet.rollbar = true
71
+ Bullet.add_footer = true
72
+ Bullet.skip_html_injection = false
73
+ Bullet.skip_http_headers = false
74
+ Bullet.stacktrace_includes = [ 'your_gem', 'your_middleware' ]
75
+ Bullet.stacktrace_excludes = [ 'their_gem', 'their_middleware', ['my_file.rb', 'my_method'], ['my_file.rb', 16..20] ]
76
+ Bullet.slack = { webhook_url: 'http://some.slack.url', channel: '#default', username: 'notifier' }
77
+ Bullet.opentelemetry = true
78
+ Bullet.raise = false
79
+ Bullet.always_append_html_body = false
80
+ Bullet.skip_user_in_notification = false
81
+ end
82
+ ```
83
+
84
+ The notifier of Bullet is a wrap of [uniform_notifier](https://github.com/flyerhzm/uniform_notifier)
85
+
86
+ The code above will enable all of the Bullet notification systems:
87
+ * `Bullet.enable`: enable Bullet gem, otherwise do nothing
88
+ * `Bullet.sentry`: add notifications to sentry
89
+ * `Bullet.alert`: pop up a JavaScript alert in the browser
90
+ * `Bullet.bullet_logger`: log to the Bullet log file (Rails.root/log/bullet.log)
91
+ * `Bullet.console`: log warnings to your browser's console.log (Safari/Webkit browsers or Firefox w/Firebug installed)
92
+ * `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.
93
+ * `Bullet.rails_logger`: add warnings directly to the Rails log
94
+ * `Bullet.honeybadger`: add notifications to Honeybadger
95
+ * `Bullet.bugsnag`: add notifications to bugsnag
96
+ * `Bullet.appsignal`: add notifications to AppSignal
97
+ * `Bullet.airbrake`: add notifications to airbrake
98
+ * `Bullet.rollbar`: add notifications to rollbar
99
+ * `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.
100
+ * `Bullet.skip_html_injection`: prevents Bullet from injecting code into the returned HTML. This must be false for receiving alerts, showing the footer or console logging.
101
+ * `Bullet.skip_http_headers`: don't add headers to API requests, and remove the javascript that relies on them. Note that this prevents bullet from logging warnings to the browser console or updating the footer.
102
+ * `Bullet.stacktrace_includes`: include paths with any of these substrings in the stack trace, even if they are not in your main app
103
+ * `Bullet.stacktrace_excludes`: ignore paths with any of these substrings in the stack trace, even if they are not in your main app.
104
+ Each item can be a string (match substring), a regex, or an array where the first item is a path to match, and the second
105
+ item is a line number, a Range of line numbers, or a (bare) method name, to exclude only particular lines in a file.
106
+ * `Bullet.slack`: add notifications to slack
107
+ * `Bullet.opentelemetry`: add notifications to OpenTelemetry
108
+ * `Bullet.raise`: raise errors, useful for making your specs fail unless they have optimized queries
109
+ * `Bullet.always_append_html_body`: always append the html body even if no notifications are present. Note: `console` or `add_footer` must also be true. Useful for Single Page Applications where the initial page load might not have any notifications present.
110
+ * `Bullet.skip_user_in_notification`: exclude the OS user (`whoami`) from notifications.
111
+
112
+
113
+ Bullet also allows you to disable any of its detectors.
114
+
115
+ ```ruby
116
+ # Each of these settings defaults to true
117
+
118
+ # Detect N+1 queries
119
+ Bullet.n_plus_one_query_enable = false
120
+
121
+ # Detect eager-loaded associations which are not used
122
+ Bullet.unused_eager_loading_enable = false
123
+
124
+ # Detect unnecessary COUNT queries which could be avoided
125
+ # with a counter_cache
126
+ Bullet.counter_cache_enable = false
127
+ ```
128
+
129
+ ## Safe list
130
+
131
+ Sometimes Bullet may notify you of query problems you don't care to fix, or
132
+ which come from outside your code. You can add them to a safe list to ignore them:
133
+
134
+ ```ruby
135
+ Bullet.add_safelist :type => :n_plus_one_query, :class_name => "Post", :association => :comments
136
+ Bullet.add_safelist :type => :unused_eager_loading, :class_name => "Post", :association => :comments
137
+ Bullet.add_safelist :type => :counter_cache, :class_name => "Country", :association => :cities
138
+ ```
139
+
140
+ If you want to skip bullet in some specific controller actions, you can
141
+ do like
142
+
143
+ ```ruby
144
+ class ApplicationController < ActionController::Base
145
+ around_action :skip_bullet, if: -> { defined?(Bullet) }
146
+
147
+ def skip_bullet
148
+ previous_value = Bullet.enable?
149
+ Bullet.enable = false
150
+ yield
151
+ ensure
152
+ Bullet.enable = previous_value
153
+ end
154
+ end
155
+ ```
156
+
157
+ ## Log
158
+
159
+ The Bullet log `log/bullet.log` will look something like this:
160
+
161
+ * N+1 Query:
162
+
163
+ ```
164
+ 2009-08-25 20:40:17[INFO] USE eager loading detected:
165
+ Post => [:comments]·
166
+ Add to your query: .includes([:comments])
167
+ 2009-08-25 20:40:17[INFO] Call stack
168
+ /Users/richard/Downloads/test/app/views/posts/index.html.erb:8:in `each'
169
+ /Users/richard/Downloads/test/app/controllers/posts_controller.rb:7:in `index'
170
+ ```
171
+
172
+ 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.
173
+
174
+ * Unused eager loading:
175
+
176
+ ```
177
+ 2009-08-25 20:53:56[INFO] AVOID eager loading detected
178
+ Post => [:comments]·
179
+ Remove from your query: .includes([:comments])
180
+ 2009-08-25 20:53:56[INFO] Call stack
181
+ ```
182
+
183
+ These lines are notifications that unused eager loadings have been encountered.
184
+
185
+ * Need counter cache:
186
+
187
+ ```
188
+ 2009-09-11 09:46:50[INFO] Need Counter Cache
189
+ Post => [:comments]
190
+ ```
191
+
192
+ ## XMPP/Jabber and Airbrake Support
193
+
194
+ see [https://github.com/flyerhzm/uniform_notifier](https://github.com/flyerhzm/uniform_notifier)
195
+
196
+ ## Growl Support
197
+
198
+ Growl support is dropped from uniform_notifier 1.16.0, if you still want it, please use uniform_notifier 1.15.0.
199
+
200
+ ## URL query control
201
+
202
+ You can add the URL query parameter `skip_html_injection` to make the current HTML request behave as if `Bullet.skip_html_injection` is enabled,
203
+ e.g. `http://localhost:3000/posts?skip_html_injection=true`
204
+
205
+ ## Important
206
+
207
+ If you find Bullet does not work for you, *please disable your browser's cache*.
208
+
209
+ ## Advanced
210
+
211
+ ### Work with ActiveJob
212
+
213
+ Include `Bullet::ActiveJob` in your `ApplicationJob`.
214
+
215
+ ```ruby
216
+ class ApplicationJob < ActiveJob::Base
217
+ include Bullet::ActiveJob if Rails.env.development?
218
+ end
219
+ ```
220
+
221
+ ### Work with other background job solution
222
+
223
+ Use the Bullet.profile method.
224
+
225
+ ```ruby
226
+ class ApplicationJob < ActiveJob::Base
227
+ around_perform do |_job, block|
228
+ Bullet.profile do
229
+ block.call
230
+ end
231
+ end
232
+ end
233
+ ```
234
+
235
+ ### Work with sinatra
236
+
237
+ Configure and use `Bullet::Rack`.
238
+
239
+ ```ruby
240
+ configure :development do
241
+ Bullet.enable = true
242
+ Bullet.bullet_logger = true
243
+ use Bullet::Rack
244
+ end
245
+ ```
246
+
247
+ If your application generates a Content-Security-Policy via a separate middleware, ensure that `Bullet::Rack` is loaded _before_ that middleware.
248
+
249
+ ### Run in tests
250
+
251
+ First you need to enable Bullet in the test environment.
252
+
253
+ ```ruby
254
+ # config/environments/test.rb
255
+ config.after_initialize do
256
+ Bullet.enable = true
257
+ Bullet.bullet_logger = true
258
+ Bullet.raise = true # raise an error if n+1 query occurs
259
+ end
260
+ ```
261
+
262
+ **Note:** Controller and integration tests work automatically because Bullet's Rack middleware wraps each HTTP request with `Bullet.start_request` and `Bullet.end_request`. However, model tests and other tests that don't go through the Rack middleware (like direct model method calls) require manual wrapping with the test helper code below.
263
+
264
+ Then wrap each test in the Bullet api.
265
+
266
+ With RSpec:
267
+
268
+ ```ruby
269
+ # spec/rails_helper.rb
270
+ RSpec.configure do |config|
271
+ config.before(:each) do
272
+ Bullet.start_request
273
+ end
274
+
275
+ config.after(:each) do
276
+ Bullet.perform_out_of_channel_notifications if Bullet.notification?
277
+ Bullet.end_request
278
+ end
279
+ end
280
+ ```
281
+
282
+ With Minitest:
283
+
284
+ ```ruby
285
+ # test/test_helper.rb
286
+ module ActiveSupport
287
+ class TestCase
288
+ def before_setup
289
+ Bullet.start_request
290
+ super
291
+ end
292
+
293
+ def after_teardown
294
+ super
295
+ Bullet.perform_out_of_channel_notifications if Bullet.notification?
296
+ Bullet.end_request
297
+ end
298
+ end
299
+ end
300
+ ```
301
+
302
+ ## Debug Mode
303
+
304
+ Bullet outputs some details info, to enable debug mode, set
305
+ `BULLET_DEBUG=true` env.
306
+
307
+ ## Contributors
308
+
309
+ [https://github.com/flyerhzm/bullet/contributors](https://github.com/flyerhzm/bullet/contributors)
310
+
311
+ ## Demo
312
+
313
+ Bullet is designed to function as you browse through your application in development. To see it in action,
314
+ you can follow these steps to create, detect, and fix example query problems.
315
+
316
+ 1\. Create an example application
317
+
318
+ ```
319
+ $ rails new test_bullet
320
+ $ cd test_bullet
321
+ $ rails g scaffold post name:string
322
+ $ rails g scaffold comment name:string post_id:integer
323
+ $ bundle exec rails db:migrate
324
+ ```
325
+
326
+ 2\. Change `app/models/post.rb` and `app/models/comment.rb`
327
+
328
+ ```ruby
329
+ class Post < ApplicationRecord
330
+ has_many :comments
331
+ end
332
+
333
+ class Comment < ApplicationRecord
334
+ belongs_to :post
335
+ end
336
+ ```
337
+
338
+ 3\. Go to `rails c` and execute
339
+
340
+ ```ruby
341
+ post1 = Post.create(:name => 'first')
342
+ post2 = Post.create(:name => 'second')
343
+ post1.comments.create(:name => 'first')
344
+ post1.comments.create(:name => 'second')
345
+ post2.comments.create(:name => 'third')
346
+ post2.comments.create(:name => 'fourth')
347
+ ```
348
+
349
+ 4\. Change the `app/views/posts/index.html.erb` to produce a N+1 query
350
+
351
+ ```
352
+ <% @posts.each do |post| %>
353
+ <tr>
354
+ <td><%= post.name %></td>
355
+ <td><%= post.comments.map(&:name) %></td>
356
+ <td><%= link_to 'Show', post %></td>
357
+ <td><%= link_to 'Edit', edit_post_path(post) %></td>
358
+ <td><%= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete %></td>
359
+ </tr>
360
+ <% end %>
361
+ ```
362
+
363
+ 5\. Add the `bullet` gem to the `Gemfile`
364
+
365
+ ```ruby
366
+ gem "bullet"
367
+ ```
368
+
369
+ And run
370
+
371
+ ```
372
+ bundle install
373
+ ```
374
+
375
+ 6\. enable the Bullet gem with generate command
376
+
377
+ ```
378
+ bundle exec rails g bullet:install
379
+ ```
380
+
381
+ 7\. Start the server
382
+
383
+ ```
384
+ $ rails s
385
+ ```
386
+
387
+ 8\. Visit `http://localhost:3000/posts` in browser, and you will see a popup alert box that says
388
+
389
+ ```
390
+ The request has unused preload associations as follows:
391
+ None
392
+ The request has N+1 queries as follows:
393
+ model: Post => associations: [comment]
394
+ ```
395
+
396
+ which means there is a N+1 query from the Post object to its Comment association.
397
+
398
+ In the meantime, there's a log appended into `log/bullet.log` file
399
+
400
+ ```
401
+ 2010-03-07 14:12:18[INFO] N+1 Query in /posts
402
+ Post => [:comments]
403
+ Add to your finder: :include => [:comments]
404
+ 2010-03-07 14:12:18[INFO] N+1 Query method call stack
405
+ /home/flyerhzm/Downloads/test_bullet/app/views/posts/index.html.erb:14:in `_render_template__600522146_80203160_0'
406
+ /home/flyerhzm/Downloads/test_bullet/app/views/posts/index.html.erb:11:in `each'
407
+ /home/flyerhzm/Downloads/test_bullet/app/views/posts/index.html.erb:11:in `_render_template__600522146_80203160_0'
408
+ /home/flyerhzm/Downloads/test_bullet/app/controllers/posts_controller.rb:7:in `index'
409
+ ```
410
+
411
+ The generated SQL is:
412
+
413
+ ```
414
+ Post Load (1.0ms) SELECT * FROM "posts"
415
+ Comment Load (0.4ms) SELECT * FROM "comments" WHERE ("comments".post_id = 1)
416
+ Comment Load (0.3ms) SELECT * FROM "comments" WHERE ("comments".post_id = 2)
417
+ ```
418
+
419
+ 9\. To fix the N+1 query, change `app/controllers/posts_controller.rb` file
420
+
421
+ ```ruby
422
+ def index
423
+ @posts = Post.includes(:comments)
424
+
425
+ respond_to do |format|
426
+ format.html # index.html.erb
427
+ format.xml { render :xml => @posts }
428
+ end
429
+ end
430
+ ```
431
+
432
+ 10\. Refresh `http://localhost:3000/posts`. Now there's no alert box and nothing new in the log.
433
+
434
+ The generated SQL is:
435
+
436
+ ```
437
+ Post Load (0.5ms) SELECT * FROM "posts"
438
+ Comment Load (0.5ms) SELECT "comments".* FROM "comments" WHERE ("comments".post_id IN (1,2))
439
+ ```
440
+
441
+ N+1 query fixed. Cool!
442
+
443
+ 11\. Now simulate unused eager loading. Change
444
+ `app/controllers/posts_controller.rb` and
445
+ `app/views/posts/index.html.erb`
446
+
447
+ ```ruby
448
+ def index
449
+ @posts = Post.includes(:comments)
450
+
451
+ respond_to do |format|
452
+ format.html # index.html.erb
453
+ format.xml { render :xml => @posts }
454
+ end
455
+ end
456
+ ```
457
+
458
+ ```
459
+ <% @posts.each do |post| %>
460
+ <tr>
461
+ <td><%= post.name %></td>
462
+ <td><%= link_to 'Show', post %></td>
463
+ <td><%= link_to 'Edit', edit_post_path(post) %></td>
464
+ <td><%= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete %></td>
465
+ </tr>
466
+ <% end %>
467
+ ```
468
+
469
+ 12\. Refresh `http://localhost:3000/posts`, and you will see a popup alert box that says
470
+
471
+ ```
472
+ The request has unused preload associations as follows:
473
+ model: Post => associations: [comment]
474
+ The request has N+1 queries as follows:
475
+ None
476
+ ```
477
+
478
+ Meanwhile, there's a line appended to `log/bullet.log`
479
+
480
+ ```
481
+ 2009-08-25 21:13:22[INFO] Unused preload associations: PATH_INFO: /posts; model: Post => associations: [comments]·
482
+ Remove from your finder: :include => [:comments]
483
+ ```
484
+
485
+ 13\. Simulate counter_cache. Change `app/controllers/posts_controller.rb`
486
+ and `app/views/posts/index.html.erb`
487
+
488
+ ```ruby
489
+ def index
490
+ @posts = Post.all
491
+
492
+ respond_to do |format|
493
+ format.html # index.html.erb
494
+ format.xml { render :xml => @posts }
495
+ end
496
+ end
497
+ ```
498
+
499
+ ```
500
+ <% @posts.each do |post| %>
501
+ <tr>
502
+ <td><%= post.name %></td>
503
+ <td><%= post.comments.size %></td>
504
+ <td><%= link_to 'Show', post %></td>
505
+ <td><%= link_to 'Edit', edit_post_path(post) %></td>
506
+ <td><%= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete %></td>
507
+ </tr>
508
+ <% end %>
509
+ ```
510
+
511
+ 14\. Refresh `http://localhost:3000/posts`, then you will see a popup alert box that says
512
+
513
+ ```
514
+ Need counter cache
515
+ Post => [:comments]
516
+ ```
517
+
518
+ Meanwhile, there's a line appended to `log/bullet.log`
519
+
520
+ ```
521
+ 2009-09-11 10:07:10[INFO] Need Counter Cache
522
+ Post => [:comments]
523
+ ```
524
+
525
+ Copyright (c) 2009 - 2022 Richard Huang (flyerhzm@gmail.com), released under the MIT license
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bullet
4
+ module ActiveJob
5
+ def self.included(base)
6
+ base.class_eval do
7
+ around_perform do |_job, block|
8
+ Bullet.profile { block.call }
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end