bullet 5.5.0 → 5.8.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.
Files changed (109) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -5
  3. data/CHANGELOG.md +31 -1
  4. data/Gemfile +6 -1
  5. data/Gemfile.rails-5.0 +1 -1
  6. data/Gemfile.rails-5.1 +15 -0
  7. data/Gemfile.rails-5.2 +15 -0
  8. data/Guardfile +2 -2
  9. data/Hacking.md +1 -1
  10. data/README.md +20 -23
  11. data/Rakefile +20 -21
  12. data/bullet.gemspec +20 -15
  13. data/lib/bullet/active_record4.rb +18 -14
  14. data/lib/bullet/active_record41.rb +16 -14
  15. data/lib/bullet/active_record42.rb +24 -22
  16. data/lib/bullet/active_record5.rb +102 -91
  17. data/lib/bullet/active_record52.rb +232 -0
  18. data/lib/bullet/dependency.rb +9 -1
  19. data/lib/bullet/detector/association.rb +17 -14
  20. data/lib/bullet/detector/base.rb +2 -0
  21. data/lib/bullet/detector/counter_cache.rb +14 -10
  22. data/lib/bullet/detector/n_plus_one_query.rb +21 -17
  23. data/lib/bullet/detector/unused_eager_loading.rb +30 -24
  24. data/lib/bullet/detector.rb +2 -0
  25. data/lib/bullet/ext/object.rb +6 -4
  26. data/lib/bullet/ext/string.rb +3 -1
  27. data/lib/bullet/mongoid4x.rb +7 -2
  28. data/lib/bullet/mongoid5x.rb +7 -2
  29. data/lib/bullet/mongoid6x.rb +11 -6
  30. data/lib/bullet/notification/base.rb +26 -19
  31. data/lib/bullet/notification/counter_cache.rb +3 -1
  32. data/lib/bullet/notification/n_plus_one_query.rb +7 -4
  33. data/lib/bullet/notification/unused_eager_loading.rb +7 -4
  34. data/lib/bullet/notification.rb +2 -0
  35. data/lib/bullet/notification_collector.rb +2 -1
  36. data/lib/bullet/rack.rb +22 -18
  37. data/lib/bullet/registry/association.rb +2 -0
  38. data/lib/bullet/registry/base.rb +2 -0
  39. data/lib/bullet/registry/object.rb +2 -0
  40. data/lib/bullet/registry.rb +2 -0
  41. data/lib/bullet/stack_trace_filter.rb +56 -18
  42. data/lib/bullet/version.rb +3 -2
  43. data/lib/bullet.rb +43 -33
  44. data/lib/generators/bullet/install_generator.rb +48 -0
  45. data/perf/benchmark.rb +12 -12
  46. data/rails/init.rb +2 -0
  47. data/spec/bullet/detector/association_spec.rb +6 -4
  48. data/spec/bullet/detector/base_spec.rb +2 -0
  49. data/spec/bullet/detector/counter_cache_spec.rb +13 -11
  50. data/spec/bullet/detector/n_plus_one_query_spec.rb +71 -46
  51. data/spec/bullet/detector/unused_eager_loading_spec.rb +21 -19
  52. data/spec/bullet/ext/object_spec.rb +10 -8
  53. data/spec/bullet/ext/string_spec.rb +7 -5
  54. data/spec/bullet/notification/base_spec.rb +39 -38
  55. data/spec/bullet/notification/counter_cache_spec.rb +5 -3
  56. data/spec/bullet/notification/n_plus_one_query_spec.rb +5 -3
  57. data/spec/bullet/notification/unused_eager_loading_spec.rb +4 -2
  58. data/spec/bullet/notification_collector_spec.rb +12 -10
  59. data/spec/bullet/rack_spec.rb +48 -47
  60. data/spec/bullet/registry/association_spec.rb +12 -10
  61. data/spec/bullet/registry/base_spec.rb +22 -20
  62. data/spec/bullet/registry/object_spec.rb +6 -4
  63. data/spec/bullet_spec.rb +24 -3
  64. data/spec/integration/{active_record4 → active_record}/association_spec.rb +176 -114
  65. data/spec/integration/counter_cache_spec.rb +15 -13
  66. data/spec/integration/mongoid/association_spec.rb +35 -33
  67. data/spec/models/address.rb +2 -0
  68. data/spec/models/author.rb +2 -0
  69. data/spec/models/base_user.rb +2 -0
  70. data/spec/models/category.rb +2 -0
  71. data/spec/models/city.rb +2 -0
  72. data/spec/models/client.rb +4 -0
  73. data/spec/models/comment.rb +3 -1
  74. data/spec/models/company.rb +2 -0
  75. data/spec/models/country.rb +2 -0
  76. data/spec/models/document.rb +4 -2
  77. data/spec/models/entry.rb +2 -0
  78. data/spec/models/firm.rb +3 -0
  79. data/spec/models/folder.rb +2 -0
  80. data/spec/models/group.rb +4 -0
  81. data/spec/models/mongoid/address.rb +3 -1
  82. data/spec/models/mongoid/category.rb +4 -2
  83. data/spec/models/mongoid/comment.rb +3 -1
  84. data/spec/models/mongoid/company.rb +3 -1
  85. data/spec/models/mongoid/entry.rb +3 -1
  86. data/spec/models/mongoid/post.rb +6 -4
  87. data/spec/models/mongoid/user.rb +2 -0
  88. data/spec/models/newspaper.rb +3 -1
  89. data/spec/models/page.rb +2 -0
  90. data/spec/models/person.rb +2 -0
  91. data/spec/models/pet.rb +2 -0
  92. data/spec/models/post.rb +17 -0
  93. data/spec/models/relationship.rb +2 -0
  94. data/spec/models/reply.rb +2 -0
  95. data/spec/models/student.rb +2 -0
  96. data/spec/models/submission.rb +2 -0
  97. data/spec/models/teacher.rb +2 -0
  98. data/spec/models/user.rb +2 -0
  99. data/spec/models/writer.rb +2 -0
  100. data/spec/spec_helper.rb +15 -13
  101. data/spec/support/bullet_ext.rb +2 -0
  102. data/spec/support/mongo_seed.rb +36 -42
  103. data/spec/support/rack_double.rb +13 -19
  104. data/spec/support/sqlite_seed.rb +84 -76
  105. data/tasks/bullet_tasks.rake +4 -2
  106. data/test.sh +2 -0
  107. data/update.sh +2 -0
  108. metadata +17 -11
  109. data/spec/integration/active_record5/association_spec.rb +0 -768
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7f8cac0418ea4a1bb9f8abc6c12e84022f2f118d
4
- data.tar.gz: ebdf99115037dec22a5480a63d3bed5f15956dda
3
+ metadata.gz: 0b65855ae5365567a18d1fb6ffdee5046b8cec35
4
+ data.tar.gz: 8df6b7afd18400dd2fe9bf39ec4a537fa04228af
5
5
  SHA512:
6
- metadata.gz: 0904f996964a403a495af310bab8a0612e614eb72a71d08646948508c25d4bf36d2b939da65156a5fc81595477820e0f123aa2a88d618fe97e28e81a6b6f8ada
7
- data.tar.gz: d491e12ccce38a26a5e3d27d3f6b84acafe34bb7b6aff56b78a8e22a73a5a3abf88443110587de0080e50b32ef70d8ca387eab5faac0b1bec16efed04bf3acc1
6
+ metadata.gz: 212cf02f1520dfaf752f794e42e9b2611fa0eca8b786bf5ef281c36c416ddf24016a524029614447c6241ebb734a2491ab554fa505544d7a7bc6f2e5b767527d
7
+ data.tar.gz: d2d71ceb54033f58cb6d675ea88268f130a0ea8bcfd7b4987486e374a2d2a3fc9169691ff20a9ca0fd9cf2787656dacc19649a8473879e9d1d68484597ccc18b
data/.travis.yml CHANGED
@@ -3,14 +3,10 @@ language: ruby
3
3
  rvm:
4
4
  - 2.3.0
5
5
  gemfile:
6
+ - Gemfile.rails-5.1
6
7
  - Gemfile.rails-5.0
7
8
  - Gemfile.rails-4.2
8
9
  - Gemfile.rails-4.1
9
10
  - Gemfile.rails-4.0
10
- - Gemfile.mongoid-6.0
11
- - Gemfile.mongoid-5.0
12
- - Gemfile.mongoid-4.0
13
11
  env:
14
12
  - DB=sqlite
15
- services:
16
- - mongodb
data/CHANGELOG.md CHANGED
@@ -1,4 +1,34 @@
1
- # Next Release
1
+ ## Next Release
2
+
3
+ ## 5.8.0 (10/29/2018)
4
+
5
+ * Fix through reflection for rails 5.x
6
+ * Fix false positive in after_save/after_create callbacks
7
+ * Don't triger a preload error on "manual" preloads
8
+ * Avoid Bullet from making extra queries in mongoid6
9
+ * Support option for #first and #last on mongoid6.x
10
+ * Fix duplicate logs in mongoid 4.x and 5.x version
11
+ * Use caller for ruby 1.9 while caller_locations for 2.0+
12
+ * Extend stacktrace matching for sub-file precision
13
+ * Exclude configured bundler path in addition to '/vendor'
14
+ * Fix `caller_path` in `excluded_stacktrace_path`
15
+ * Update `uniform_notifier` dependency to add Sentry support
16
+ * Integrate awesomecode.io and refactor code
17
+
18
+ ## 5.7.0 (12/03/2017)
19
+
20
+ * Support rails 5.2
21
+ * Implement Bullet.delete_whitelist to delete a specific whitelist definition
22
+ * Fix caller_path in the case of nil
23
+
24
+ ## 5.6.0 (07/16/2017)
25
+
26
+ * Migrate alias_method to Module#prepend
27
+ * Add install generator
28
+ * Stack trace filter
29
+ * Fix rails 5.1 compatibility
30
+ * Fix inverse_of for rails 5
31
+ * Fix detect file attachment for rack #319
2
32
 
3
33
  ## 5.5.0 (12/30/2016)
4
34
 
data/Gemfile CHANGED
@@ -1,8 +1,13 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+ git_source(:github) do |repo_name|
4
+ repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?('/')
5
+ "https://github.com/#{repo_name}.git"
6
+ end
7
+
3
8
  gemspec
4
9
 
5
- gem 'rails', github: 'rails/rails'
10
+ gem 'rails', github: 'rails'
6
11
  gem 'sqlite3', platforms: [:ruby]
7
12
  gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
13
  gem 'activerecord-import'
data/Gemfile.rails-5.0 CHANGED
@@ -2,7 +2,7 @@ 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'
data/Gemfile.rails-5.1 ADDED
@@ -0,0 +1,15 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem 'rails', '~> 5.1.0'
6
+ gem 'sqlite3'
7
+ gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
+ gem 'activerecord-import'
9
+
10
+ gem "rspec"
11
+
12
+ platforms :rbx do
13
+ gem 'rubysl', '~> 2.0'
14
+ gem 'rubinius-developer_tools'
15
+ end
data/Gemfile.rails-5.2 ADDED
@@ -0,0 +1,15 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem 'rails', '~> 5.2.0'
6
+ gem 'sqlite3'
7
+ gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
+ gem 'activerecord-import'
9
+
10
+ gem "rspec"
11
+
12
+ platforms :rbx do
13
+ gem 'rubysl', '~> 2.0'
14
+ gem 'rubinius-developer_tools'
15
+ end
data/Guardfile CHANGED
@@ -1,8 +1,8 @@
1
1
  # A sample Guardfile
2
2
  # More info at https://github.com/guard/guard#readme
3
3
 
4
- guard 'rspec', :version => 2, :all_after_pass => false, :all_on_start => false, :cli => "--color --format nested --fail-fast" do
4
+ guard 'rspec', version: 2, all_after_pass: false, all_on_start: false, cli: '--color --format nested --fail-fast' do
5
5
  watch(%r{^spec/.+_spec\.rb$})
6
6
  watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
7
- watch('spec/spec_helper.rb') { "spec" }
7
+ watch('spec/spec_helper.rb') { 'spec' }
8
8
  end
data/Hacking.md CHANGED
@@ -28,7 +28,7 @@ So the flow of a request goes like this:
28
28
  the notification collector
29
29
  2. The request is handled by Rails, and the installed ActiveRecord extensions
30
30
  trigger Detector callbacks
31
- 3. Detectors once called, will determine whether something noteworthy happend.
31
+ 3. Detectors once called, will determine whether something noteworthy happened.
32
32
  If yes, then a Notification is created and stored in the notification collector.
33
33
  4. Rails finishes handling the request
34
34
  5. For each notification in the collector, Bullet will iterate over each
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/bullet.png)](http://badge.fury.io/rb/bullet)
4
4
  [![Build Status](https://secure.travis-ci.org/flyerhzm/bullet.png)](http://travis-ci.org/flyerhzm/bullet)
5
- <a href="https://codeclimate.com/github/flyerhzm/bullet"><img src="https://codeclimate.com/github/flyerhzm/bullet.png" /></a>
5
+ [![AwesomeCode Status for flyerhzm/bullet](https://awesomecode.io/projects/6755235b-e2c1-459e-bf92-b8b13d0c0472/status)](https://awesomecode.io/repos/flyerhzm/bullet)
6
6
  [![Coderwall Endorse](http://api.coderwall.com/flyerhzm/endorsecount.png)](http://coderwall.com/flyerhzm)
7
7
 
8
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.
@@ -13,7 +13,7 @@ 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
16
+ If you use activerecord 3.x, please use bullet < 5.5.0
17
17
 
18
18
  ## External Introduction
19
19
 
@@ -34,7 +34,7 @@ or add it into a Gemfile (Bundler):
34
34
 
35
35
 
36
36
  ```ruby
37
- gem "bullet", :group => "development"
37
+ gem 'bullet', group: 'development'
38
38
  ```
39
39
 
40
40
  **Note**: make sure `bullet` gem is added after activerecord (rails) and
@@ -48,6 +48,7 @@ Bullet won't do ANYTHING unless you tell it to explicitly. Append to
48
48
  ```ruby
49
49
  config.after_initialize do
50
50
  Bullet.enable = true
51
+ Bullet.sentry = true
51
52
  Bullet.alert = true
52
53
  Bullet.bullet_logger = true
53
54
  Bullet.console = true
@@ -63,30 +64,34 @@ config.after_initialize do
63
64
  Bullet.rollbar = true
64
65
  Bullet.add_footer = true
65
66
  Bullet.stacktrace_includes = [ 'your_gem', 'your_middleware' ]
66
- Bullet.stacktrace_excludes = [ 'their_gem', 'their_middleware' ]
67
+ Bullet.stacktrace_excludes = [ 'their_gem', 'their_middleware', ['my_file.rb', 'my_method'], ['my_file.rb', 16..20] ]
67
68
  Bullet.slack = { webhook_url: 'http://some.slack.url', channel: '#default', username: 'notifier' }
68
69
  end
69
70
  ```
70
71
 
71
72
  The notifier of Bullet is a wrap of [uniform_notifier](https://github.com/flyerhzm/uniform_notifier)
72
73
 
73
- The code above will enable all seven of the Bullet notification systems:
74
+ The code above will enable all of the Bullet notification systems:
74
75
  * `Bullet.enable`: enable Bullet gem, otherwise do nothing
75
76
  * `Bullet.alert`: pop up a JavaScript alert in the browser
76
77
  * `Bullet.bullet_logger`: log to the Bullet log file (Rails.root/log/bullet.log)
78
+ * `Bullet.console`: log warnings to your browser's console.log (Safari/Webkit browsers or Firefox w/Firebug installed)
79
+ * `Bullet.growl`: pop up Growl warnings if your system has Growl installed. Requires a little bit of configuration
80
+ * `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.
77
81
  * `Bullet.rails_logger`: add warnings directly to the Rails log
78
82
  * `Bullet.honeybadger`: add notifications to Honeybadger
79
83
  * `Bullet.bugsnag`: add notifications to bugsnag
80
84
  * `Bullet.airbrake`: add notifications to airbrake
81
85
  * `Bullet.rollbar`: add notifications to rollbar
82
- * `Bullet.console`: log warnings to your browser's console.log (Safari/Webkit browsers or Firefox w/Firebug installed)
83
- * `Bullet.growl`: pop up Growl warnings if your system has Growl installed. Requires a little bit of configuration
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.
85
- * `Bullet.raise`: raise errors, useful for making your specs fail unless they have optimized queries
86
+ * `Bullet.sentry`: add notifications to sentry
86
87
  * `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.
87
88
  * `Bullet.stacktrace_includes`: include paths with any of these substrings in the stack trace, even if they are not in your main app
88
89
  * `Bullet.stacktrace_excludes`: ignore paths with any of these substrings in the stack trace, even if they are not in your main app.
90
+ 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
91
+ item is a line number, a Range of line numbers, or a (bare) method name, to exclude only particular lines in a file.
89
92
  * `Bullet.slack`: add notifications to slack
93
+ * `Bullet.raise`: raise errors, useful for making your specs fail unless they have optimized queries
94
+
90
95
 
91
96
  Bullet also allows you to disable any of its detectors.
92
97
 
@@ -123,10 +128,11 @@ class ApplicationController < ActionController::Base
123
128
  around_action :skip_bullet
124
129
 
125
130
  def skip_bullet
131
+ previous_value = Bullet.enable?
126
132
  Bullet.enable = false
127
133
  yield
128
134
  ensure
129
- Bullet.enable = true
135
+ Bullet.enable = previous_value
130
136
  end
131
137
  end
132
138
  ```
@@ -177,7 +183,7 @@ If you find Bullet does not work for you, *please disable your browser's cache*.
177
183
 
178
184
  ### Profile a job
179
185
 
180
- The Bullet gem uses rack middleware to profile requests. If you want to use Bullet without an http server, like to profile a job, you can use use profile method and fetch warnings
186
+ The Bullet gem uses rack middleware to profile requests. If you want to use Bullet without an http server, like to profile a job, you can use the profile method and fetch warnings
181
187
 
182
188
  ```ruby
183
189
  Bullet.profile do
@@ -302,19 +308,10 @@ And run
302
308
  bundle install
303
309
  ```
304
310
 
305
- 6\. enable the Bullet gem in development, add a line to
306
- `config/environments/development.rb`
311
+ 6\. enable the Bullet gem with generate command
307
312
 
308
- ```ruby
309
- config.after_initialize do
310
- Bullet.enable = true
311
- Bullet.alert = true
312
- Bullet.bullet_logger = true
313
- Bullet.console = true
314
- # Bullet.growl = true
315
- Bullet.rails_logger = true
316
- Bullet.add_footer = true
317
- end
313
+ ```
314
+ bundle exec rails g bullet:install
318
315
  ```
319
316
 
320
317
  7\. Start the server
data/Rakefile CHANGED
@@ -1,52 +1,51 @@
1
- $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
2
- require "bundler"
1
+ $LOAD_PATH.unshift File.expand_path('lib', __dir__)
2
+ require 'bundler'
3
3
  Bundler.setup
4
4
 
5
- require "rake"
6
- require "rspec"
7
- require "rspec/core/rake_task"
5
+ require 'rake'
6
+ require 'rspec'
7
+ require 'rspec/core/rake_task'
8
8
 
9
- require "bullet/version"
9
+ require 'bullet/version'
10
10
 
11
11
  task :build do
12
- system "gem build bullet.gemspec"
12
+ system 'gem build bullet.gemspec'
13
13
  end
14
14
 
15
- task :install => :build do
15
+ task install: :build do
16
16
  system "sudo gem install bullet-#{Bullet::VERSION}.gem"
17
17
  end
18
18
 
19
- task :release => :build do
19
+ task release: :build do
20
20
  puts "Tagging #{Bullet::VERSION}..."
21
21
  system "git tag -a #{Bullet::VERSION} -m 'Tagging #{Bullet::VERSION}'"
22
- puts "Pushing to Github..."
23
- system "git push --tags"
24
- puts "Pushing to rubygems.org..."
22
+ puts 'Pushing to Github...'
23
+ system 'git push --tags'
24
+ puts 'Pushing to rubygems.org...'
25
25
  system "gem push bullet-#{Bullet::VERSION}.gem"
26
26
  end
27
27
 
28
28
  RSpec::Core::RakeTask.new(:spec) do |spec|
29
- spec.pattern = "spec/**/*_spec.rb"
29
+ spec.pattern = 'spec/**/*_spec.rb'
30
30
  end
31
31
 
32
32
  RSpec::Core::RakeTask.new('spec:progress') do |spec|
33
- spec.rspec_opts = %w(--format progress)
34
- spec.pattern = "spec/**/*_spec.rb"
33
+ spec.rspec_opts = %w[--format progress]
34
+ spec.pattern = 'spec/**/*_spec.rb'
35
35
  end
36
36
 
37
-
38
37
  begin
39
38
  require 'rdoc/task'
40
39
 
41
- desc "Generate documentation for the plugin."
40
+ desc 'Generate documentation for the plugin.'
42
41
  Rake::RDocTask.new do |rdoc|
43
- rdoc.rdoc_dir = "rdoc"
42
+ rdoc.rdoc_dir = 'rdoc'
44
43
  rdoc.title = "bullet #{Bullet::VERSION}"
45
- rdoc.rdoc_files.include("README*")
46
- rdoc.rdoc_files.include("lib/**/*.rb")
44
+ rdoc.rdoc_files.include('README*')
45
+ rdoc.rdoc_files.include('lib/**/*.rb')
47
46
  end
48
47
  rescue LoadError
49
48
  puts 'RDocTask is not supported for this platform'
50
49
  end
51
50
 
52
- task :default => :spec
51
+ task default: :spec
data/bullet.gemspec CHANGED
@@ -1,27 +1,32 @@
1
- lib = File.expand_path('../lib/', __FILE__)
2
- $:.unshift lib unless $:.include?(lib)
1
+ # frozen_string_literal: true
3
2
 
4
- require "bullet/version"
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift lib unless $LOAD_PATH.include?(lib)
5
+
6
+ require 'bullet/version'
5
7
 
6
8
  Gem::Specification.new do |s|
7
- s.name = "bullet"
9
+ s.name = 'bullet'
8
10
  s.version = Bullet::VERSION
9
11
  s.platform = Gem::Platform::RUBY
10
- s.authors = ["Richard Huang"]
11
- s.email = ["flyerhzm@gmail.com"]
12
- s.homepage = "http://github.com/flyerhzm/bullet"
13
- s.summary = "help to kill N+1 queries and unused eager loading."
14
- s.description = "help to kill N+1 queries and unused eager loading."
12
+ s.authors = ['Richard Huang']
13
+ s.email = ['flyerhzm@gmail.com']
14
+ s.homepage = 'https://github.com/flyerhzm/bullet'
15
+ s.summary = 'help to kill N+1 queries and unused eager loading.'
16
+ s.description = 'help to kill N+1 queries and unused eager loading.'
17
+ s.metadata = {
18
+ 'changelog_uri' => 'https://github.com/flyerhzm/bullet/blob/master/CHANGELOG.md',
19
+ 'source_code_uri' => 'https://github.com/flyerhzm/bullet'
20
+ }
15
21
 
16
- s.license = 'MIT'
22
+ s.license = 'MIT'
17
23
 
18
- s.required_rubygems_version = ">= 1.3.6"
24
+ s.required_rubygems_version = '>= 1.3.6'
19
25
 
20
- s.add_runtime_dependency "activesupport", ">= 3.0.0"
21
- s.add_runtime_dependency "uniform_notifier", "~> 1.10.0"
26
+ s.add_runtime_dependency 'activesupport', '>= 3.0.0'
27
+ s.add_runtime_dependency 'uniform_notifier', '~> 1.11'
22
28
 
23
29
  s.files = `git ls-files`.split("\n")
24
30
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
25
- s.require_paths = ["lib"]
31
+ s.require_paths = ['lib']
26
32
  end
27
-
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Bullet
2
4
  module ActiveRecord
3
5
  def self.enable
@@ -46,21 +48,12 @@ module Bullet
46
48
  end
47
49
 
48
50
  ::ActiveRecord::Persistence.class_eval do
49
- def save_with_bullet(*args, &proc)
50
- was_new_record = new_record?
51
- save_without_bullet(*args, &proc).tap do |result|
52
- Bullet::Detector::NPlusOneQuery.add_impossible_object(self) if result && was_new_record
53
- end
54
- end
55
- alias_method_chain :save, :bullet
56
-
57
- def save_with_bullet!(*args, &proc)
58
- was_new_record = new_record?
59
- save_without_bullet!(*args, &proc).tap do |result|
60
- Bullet::Detector::NPlusOneQuery.add_impossible_object(self) if result && was_new_record
51
+ def _create_record_with_bullet(*args)
52
+ _create_record_without_bullet(*args).tap do
53
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(self)
61
54
  end
62
55
  end
63
- alias_method_chain :save!, :bullet
56
+ alias_method_chain :_create_record, :bullet
64
57
  end
65
58
 
66
59
  ::ActiveRecord::Associations::Preloader.class_eval do
@@ -72,6 +65,7 @@ module Bullet
72
65
  if Bullet.start?
73
66
  records = [records].flatten.compact.uniq
74
67
  return if records.empty?
68
+
75
69
  records.each do |record|
76
70
  Bullet::Detector::Association.add_object_associations(record, associations)
77
71
  end
@@ -105,7 +99,7 @@ module Bullet
105
99
  records = origin_instantiate(rows)
106
100
 
107
101
  if Bullet.start?
108
- @bullet_eager_loadings.each do |klazz, eager_loadings_hash|
102
+ @bullet_eager_loadings.each do |_klazz, eager_loadings_hash|
109
103
  objects = eager_loadings_hash.keys
110
104
  Bullet::Detector::UnusedEagerLoading.add_eager_loadings(objects, eager_loadings_hash[objects.first].to_a)
111
105
  end
@@ -187,6 +181,7 @@ module Bullet
187
181
  ::ActiveRecord::Associations::HasManyAssociation.class_eval do
188
182
  alias_method :origin_has_cached_counter?, :has_cached_counter?
189
183
 
184
+ # rubocop:disable Style/MethodCallWithoutArgsParentheses
190
185
  def has_cached_counter?(reflection = reflection())
191
186
  result = origin_has_cached_counter?(reflection)
192
187
  if Bullet.start? && !result
@@ -194,6 +189,15 @@ module Bullet
194
189
  end
195
190
  result
196
191
  end
192
+ # rubocop:enable Style/MethodCallWithoutArgsParentheses
193
+ end
194
+
195
+ ::ActiveRecord::Associations::BelongsToAssociation.class_eval do
196
+ def writer_with_bullet(record)
197
+ Bullet::Detector::Association.add_object_associations(owner, reflection.name) if Bullet.start?
198
+ writer_without_bullet(record)
199
+ end
200
+ alias_method_chain :writer, :bullet
197
201
  end
198
202
  end
199
203
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Bullet
2
4
  module ActiveRecord
3
5
  def self.enable
@@ -48,21 +50,12 @@ module Bullet
48
50
  end
49
51
 
50
52
  ::ActiveRecord::Persistence.class_eval do
51
- def save_with_bullet(*args, &proc)
52
- was_new_record = new_record?
53
- save_without_bullet(*args, &proc).tap do |result|
54
- Bullet::Detector::NPlusOneQuery.add_impossible_object(self) if result && was_new_record
55
- end
56
- end
57
- alias_method_chain :save, :bullet
58
-
59
- def save_with_bullet!(*args, &proc)
60
- was_new_record = new_record?
61
- save_without_bullet!(*args, &proc).tap do |result|
62
- Bullet::Detector::NPlusOneQuery.add_impossible_object(self) if result && was_new_record
53
+ def _create_record_with_bullet(*args)
54
+ _create_record_without_bullet(*args).tap do
55
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(self)
63
56
  end
64
57
  end
65
- alias_method_chain :save!, :bullet
58
+ alias_method_chain :_create_record, :bullet
66
59
  end
67
60
 
68
61
  ::ActiveRecord::Associations::Preloader.class_eval do
@@ -87,6 +80,7 @@ module Bullet
87
80
  alias_method :origin_find_with_associations, :find_with_associations
88
81
  def find_with_associations
89
82
  return origin_find_with_associations { |r| yield r } if block_given?
83
+
90
84
  records = origin_find_with_associations
91
85
  if Bullet.start?
92
86
  associations = (eager_load_values + includes_values).uniq
@@ -108,7 +102,7 @@ module Bullet
108
102
  records = origin_instantiate(result_set, aliases)
109
103
 
110
104
  if Bullet.start?
111
- @bullet_eager_loadings.each do |klazz, eager_loadings_hash|
105
+ @bullet_eager_loadings.each do |_klazz, eager_loadings_hash|
112
106
  objects = eager_loadings_hash.keys
113
107
  Bullet::Detector::UnusedEagerLoading.add_eager_loadings(objects, eager_loadings_hash[objects.first].to_a)
114
108
  end
@@ -185,6 +179,14 @@ module Bullet
185
179
  origin_count_records
186
180
  end
187
181
  end
182
+
183
+ ::ActiveRecord::Associations::BelongsToAssociation.class_eval do
184
+ def writer_with_bullet(record)
185
+ Bullet::Detector::Association.add_object_associations(owner, reflection.name) if Bullet.start?
186
+ writer_without_bullet(record)
187
+ end
188
+ alias_method_chain :writer, :bullet
189
+ end
188
190
  end
189
191
  end
190
192
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Bullet
2
4
  module ActiveRecord
3
5
  def self.enable
@@ -42,21 +44,12 @@ module Bullet
42
44
  end
43
45
 
44
46
  ::ActiveRecord::Persistence.class_eval do
45
- def save_with_bullet(*args, &proc)
46
- was_new_record = new_record?
47
- save_without_bullet(*args, &proc).tap do |result|
48
- Bullet::Detector::NPlusOneQuery.add_impossible_object(self) if result && was_new_record
47
+ def _create_record_with_bullet(*args)
48
+ _create_record_without_bullet(*args).tap do
49
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(self)
49
50
  end
50
51
  end
51
- alias_method_chain :save, :bullet
52
-
53
- def save_with_bullet!(*args, &proc)
54
- was_new_record = new_record?
55
- save_without_bullet!(*args, &proc).tap do |result|
56
- Bullet::Detector::NPlusOneQuery.add_impossible_object(self) if result && was_new_record
57
- end
58
- end
59
- alias_method_chain :save!, :bullet
52
+ alias_method_chain :_create_record, :bullet
60
53
  end
61
54
 
62
55
  ::ActiveRecord::Relation.class_eval do
@@ -102,6 +95,7 @@ module Bullet
102
95
  alias_method :origin_find_with_associations, :find_with_associations
103
96
  def find_with_associations
104
97
  return origin_find_with_associations { |r| yield r } if block_given?
98
+
105
99
  records = origin_find_with_associations
106
100
  if Bullet.start?
107
101
  associations = (eager_load_values + includes_values).uniq
@@ -124,7 +118,7 @@ module Bullet
124
118
  records = origin_instantiate(result_set, aliases)
125
119
 
126
120
  if Bullet.start?
127
- @bullet_eager_loadings.each do |klazz, eager_loadings_hash|
121
+ @bullet_eager_loadings.each do |_klazz, eager_loadings_hash|
128
122
  objects = eager_loadings_hash.keys
129
123
  Bullet::Detector::UnusedEagerLoading.add_eager_loadings(objects, eager_loadings_hash[objects.first].to_a)
130
124
  end
@@ -138,14 +132,14 @@ module Bullet
138
132
  parent.children.each do |node|
139
133
  key = aliases.column_alias(node, node.primary_key)
140
134
  id = row[key]
141
- if id.nil?
142
- associations = node.reflection.name
143
- Bullet::Detector::Association.add_object_associations(ar_parent, associations)
144
- Bullet::Detector::NPlusOneQuery.call_association(ar_parent, associations)
145
- @bullet_eager_loadings[ar_parent.class] ||= {}
146
- @bullet_eager_loadings[ar_parent.class][ar_parent] ||= Set.new
147
- @bullet_eager_loadings[ar_parent.class][ar_parent] << associations
148
- end
135
+ next unless id.nil?
136
+
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
149
143
  end
150
144
  end
151
145
  end
@@ -246,6 +240,14 @@ module Bullet
246
240
  origin_count_records
247
241
  end
248
242
  end
243
+
244
+ ::ActiveRecord::Associations::BelongsToAssociation.class_eval do
245
+ def writer_with_bullet(record)
246
+ Bullet::Detector::Association.add_object_associations(owner, reflection.name) if Bullet.start?
247
+ writer_without_bullet(record)
248
+ end
249
+ alias_method_chain :writer, :bullet
250
+ end
249
251
  end
250
252
  end
251
253
  end