bullet 8.0.1 → 8.0.3

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
  SHA256:
3
- metadata.gz: eb8c8d2264141849784cb8a103b9521a8fad5ba11eba1daa9a5a576f02c2bcc6
4
- data.tar.gz: e9b5a2a2f123ad3e84007407123103535844dcde3c7e9f3da304eb019d55f96d
3
+ metadata.gz: 0b32cc08a4de57560f18996d4ff4c96cb7a8cbc36cfb6dc285f612ac8ccd8f2e
4
+ data.tar.gz: 1d5b9e6f885039b6a3208d546b2ebad0a44e8063c4e1fffc7d74790ba79c1f71
5
5
  SHA512:
6
- metadata.gz: bc9c11edab1b705ba7f51f63bf0315c94d5c3f4178684c42da4042adeef52da7570939a91556301dcb076a08a9dc816b89cd38c8a5399c7a8fe81baf2562ca01
7
- data.tar.gz: aa0cc8a93443e8fa17582ac89dca1eba8714080ebab2d0199b0a298f77ccf3f0a019b457615e18e6dd8827f3573e0fe657d9ada3c36d6e8cd588e2b2c4a4090f
6
+ metadata.gz: fb317b0bab9154eb40be0a315f1fe767ff8c227f631ee6b25e270c31422fb6aa7b4857ae7cb33b9155eb8a2300a1c52d6097fef899ad02b7cae42c8c7082e2a6
7
+ data.tar.gz: ba13a423de83f43a6a5a2d75a576e4612011c21cf835f2204cda2b02114680f03cf397b7d28f476eefd1c8e933da2a7e0ab9e860ee28f9e0dbbb1ecbf5abeef7
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  ## Next Release
2
2
 
3
+ ## 8.0.3 (04/04/2025)
4
+
5
+ * Update non persisted `inversed_objects`
6
+
7
+ ## 8.0.2 (04/02/2025)
8
+
9
+ * Do not cache `bullet_key` if object is not persisted
10
+
3
11
  ## 8.0.1 (02/10/2025)
4
12
 
5
13
  * Update benchmark to use sqlite
data/README.md CHANGED
@@ -121,8 +121,6 @@ Bullet.unused_eager_loading_enable = false
121
121
  Bullet.counter_cache_enable = false
122
122
  ```
123
123
 
124
- Note: When calling `Bullet.enable`, all other detectors are reset to their defaults (`true`) and need reconfiguring.
125
-
126
124
  ## Safe list
127
125
 
128
126
  Sometimes Bullet may notify you of query problems you don't care to fix, or
@@ -240,7 +238,7 @@ If your application generates a Content-Security-Policy via a separate middlewar
240
238
 
241
239
  ### Run in tests
242
240
 
243
- First you need to enable Bullet in test environment.
241
+ First you need to enable Bullet in the test environment.
244
242
 
245
243
  ```ruby
246
244
  # config/environments/test.rb
@@ -251,11 +249,13 @@ config.after_initialize do
251
249
  end
252
250
  ```
253
251
 
254
- Then wrap each test in Bullet api.
252
+ Then wrap each test in the Bullet api.
253
+
254
+ With RSpec:
255
255
 
256
256
  ```ruby
257
257
  # spec/rails_helper.rb
258
- if Bullet.enable?
258
+ RSpec.configure do |config|
259
259
  config.before(:each) do
260
260
  Bullet.start_request
261
261
  end
@@ -267,6 +267,26 @@ if Bullet.enable?
267
267
  end
268
268
  ```
269
269
 
270
+ With Minitest:
271
+
272
+ ```ruby
273
+ # test/test_helper.rb
274
+ module ActiveSupport
275
+ class TestCase
276
+ def before_setup
277
+ Bullet.start_request
278
+ super
279
+ end
280
+
281
+ def after_teardown
282
+ super
283
+ Bullet.perform_out_of_channel_notifications if Bullet.notification?
284
+ Bullet.end_request
285
+ end
286
+ end
287
+ end
288
+ ```
289
+
270
290
  ## Debug Mode
271
291
 
272
292
  Bullet outputs some details info, to enable debug mode, set
@@ -49,7 +49,7 @@ module Bullet
49
49
 
50
50
  ::ActiveRecord::Persistence.class_eval do
51
51
  def _create_record_with_bullet(*args)
52
- _create_record_without_bullet(*args).tap { Bullet::Detector::NPlusOneQuery.add_impossible_object(self) }
52
+ _create_record_without_bullet(*args).tap { Bullet::Detector::NPlusOneQuery.update_inversed_object(self) }
53
53
  end
54
54
  alias_method_chain :_create_record, :bullet
55
55
  end
@@ -52,7 +52,7 @@ module Bullet
52
52
 
53
53
  ::ActiveRecord::Persistence.class_eval do
54
54
  def _create_record_with_bullet(*args)
55
- _create_record_without_bullet(*args).tap { Bullet::Detector::NPlusOneQuery.add_impossible_object(self) }
55
+ _create_record_without_bullet(*args).tap { Bullet::Detector::NPlusOneQuery.update_inversed_object(self) }
56
56
  end
57
57
  alias_method_chain :_create_record, :bullet
58
58
  end
@@ -45,7 +45,7 @@ module Bullet
45
45
 
46
46
  ::ActiveRecord::Persistence.class_eval do
47
47
  def _create_record_with_bullet(*args)
48
- _create_record_without_bullet(*args).tap { Bullet::Detector::NPlusOneQuery.add_impossible_object(self) }
48
+ _create_record_without_bullet(*args).tap { Bullet::Detector::NPlusOneQuery.update_inversed_object(self) }
49
49
  end
50
50
  alias_method_chain :_create_record, :bullet
51
51
  end
@@ -4,7 +4,7 @@ module Bullet
4
4
  module SaveWithBulletSupport
5
5
  def _create_record(*)
6
6
  super do
7
- Bullet::Detector::NPlusOneQuery.add_impossible_object(self)
7
+ Bullet::Detector::NPlusOneQuery.update_inversed_object(self)
8
8
  yield(self) if block_given?
9
9
  end
10
10
  end
@@ -4,7 +4,7 @@ module Bullet
4
4
  module SaveWithBulletSupport
5
5
  def _create_record(*)
6
6
  super do
7
- Bullet::Detector::NPlusOneQuery.add_impossible_object(self)
7
+ Bullet::Detector::NPlusOneQuery.update_inversed_object(self)
8
8
  yield(self) if block_given?
9
9
  end
10
10
  end
@@ -4,7 +4,7 @@ module Bullet
4
4
  module SaveWithBulletSupport
5
5
  def _create_record(*)
6
6
  super do
7
- Bullet::Detector::NPlusOneQuery.add_impossible_object(self)
7
+ Bullet::Detector::NPlusOneQuery.update_inversed_object(self)
8
8
  yield(self) if block_given?
9
9
  end
10
10
  end
@@ -4,7 +4,7 @@ module Bullet
4
4
  module SaveWithBulletSupport
5
5
  def _create_record(*)
6
6
  super do
7
- Bullet::Detector::NPlusOneQuery.add_impossible_object(self)
7
+ Bullet::Detector::NPlusOneQuery.update_inversed_object(self)
8
8
  yield(self) if block_given?
9
9
  end
10
10
  end
@@ -4,7 +4,7 @@ module Bullet
4
4
  module SaveWithBulletSupport
5
5
  def _create_record(*)
6
6
  super do
7
- Bullet::Detector::NPlusOneQuery.add_impossible_object(self)
7
+ Bullet::Detector::NPlusOneQuery.update_inversed_object(self)
8
8
  yield(self) if block_given?
9
9
  end
10
10
  end
@@ -4,7 +4,7 @@ module Bullet
4
4
  module SaveWithBulletSupport
5
5
  def _create_record(*)
6
6
  super do
7
- Bullet::Detector::NPlusOneQuery.add_impossible_object(self)
7
+ Bullet::Detector::NPlusOneQuery.update_inversed_object(self)
8
8
  yield(self) if block_given?
9
9
  end
10
10
  end
@@ -4,7 +4,7 @@ module Bullet
4
4
  module SaveWithBulletSupport
5
5
  def _create_record(*)
6
6
  super do
7
- Bullet::Detector::NPlusOneQuery.add_impossible_object(self)
7
+ Bullet::Detector::NPlusOneQuery.update_inversed_object(self)
8
8
  yield(self) if block_given?
9
9
  end
10
10
  end
@@ -4,7 +4,7 @@ module Bullet
4
4
  module SaveWithBulletSupport
5
5
  def _create_record(*)
6
6
  super do
7
- Bullet::Detector::NPlusOneQuery.add_impossible_object(self)
7
+ Bullet::Detector::NPlusOneQuery.update_inversed_object(self)
8
8
  yield(self) if block_given?
9
9
  end
10
10
  end
@@ -56,6 +56,8 @@ module Bullet
56
56
  'mongoid7x'
57
57
  elsif mongoid8x?
58
58
  'mongoid8x'
59
+ elsif mongoid9x?
60
+ 'mongoid9x'
59
61
  else
60
62
  raise "Bullet does not support mongoid #{::Mongoid::VERSION} yet"
61
63
  end
@@ -149,5 +151,9 @@ module Bullet
149
151
  def mongoid8x?
150
152
  mongoid? && ::Mongoid::VERSION =~ /\A8/
151
153
  end
154
+
155
+ def mongoid9x?
156
+ mongoid? && ::Mongoid::VERSION =~ /\A9/
157
+ end
152
158
  end
153
159
  end
@@ -67,13 +67,23 @@ module Bullet
67
67
  def add_inversed_object(object, association)
68
68
  return unless Bullet.start?
69
69
  return unless Bullet.n_plus_one_query_enable?
70
- return unless object.bullet_primary_key_value
71
70
 
71
+ object_key = object.bullet_primary_key_value ? object.bullet_key : object.object_id
72
72
  Bullet.debug(
73
73
  'Detector::NPlusOneQuery#add_inversed_object',
74
- "object: #{object.bullet_key}, association: #{association}"
74
+ "object: #{object_key}, association: #{association}"
75
75
  )
76
- inversed_objects.add object.bullet_key, association
76
+ inversed_objects.add object_key, association
77
+ end
78
+
79
+ def update_inversed_object(object)
80
+ if inversed_objects&.key?(object.object_id)
81
+ Bullet.debug(
82
+ 'Detector::NPlusOneQuery#update_inversed_object',
83
+ "object from #{object.object_id} to #{object.bullet_key}"
84
+ )
85
+ inversed_objects.add(object.bullet_key, inversed_objects[object.object_id].to_a)
86
+ end
77
87
  end
78
88
 
79
89
  # decide whether the object.associations is unpreloaded or not.
@@ -7,17 +7,20 @@ module Bullet
7
7
  attr_writer :bullet_key, :bullet_primary_key_value
8
8
 
9
9
  def bullet_key
10
+ return "#{self.class}:" if respond_to?(:persisted?) && !persisted?
11
+
10
12
  @bullet_key ||= "#{self.class}:#{bullet_primary_key_value}"
11
13
  end
12
14
 
13
15
  def bullet_primary_key_value
14
- @bullet_primary_key_value ||= begin
15
- return if respond_to?(:persisted?) && !persisted?
16
+ return if respond_to?(:persisted?) && !persisted?
16
17
 
17
- primary_key = self.class.try(:primary_keys) || self.class.try(:primary_key) || :id
18
+ @bullet_primary_key_value ||=
19
+ begin
20
+ primary_key = self.class.try(:primary_keys) || self.class.try(:primary_key) || :id
18
21
 
19
- bullet_join_potential_composite_primary_key(primary_key)
20
- end
22
+ bullet_join_potential_composite_primary_key(primary_key)
23
+ end
21
24
  end
22
25
 
23
26
  private
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bullet
4
+ module Mongoid
5
+ def self.enable
6
+ require 'mongoid'
7
+ require 'rubygems'
8
+ ::Mongoid::Contextual::Mongo.class_eval do
9
+ alias_method :origin_first, :first
10
+ alias_method :origin_last, :last
11
+ alias_method :origin_each, :each
12
+ alias_method :origin_eager_load, :eager_load
13
+
14
+ %i[first last].each do |context|
15
+ default = Gem::Version.new(::Mongoid::VERSION) >= Gem::Version.new('7.5') ? nil : {}
16
+ define_method(context) do |opts = default|
17
+ result = send(:"origin_#{context}", opts)
18
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(result) if result
19
+ result
20
+ end
21
+ end
22
+
23
+ def each(&_block)
24
+ return to_enum unless block_given?
25
+
26
+ first_document = nil
27
+ document_count = 0
28
+
29
+ origin_each do |document|
30
+ document_count += 1
31
+
32
+ if document_count == 1
33
+ first_document = document
34
+ elsif document_count == 2
35
+ Bullet::Detector::NPlusOneQuery.add_possible_objects([first_document, document])
36
+ yield(first_document)
37
+ first_document = nil
38
+ yield(document)
39
+ else
40
+ Bullet::Detector::NPlusOneQuery.add_possible_objects(document)
41
+ yield(document)
42
+ end
43
+ end
44
+
45
+ if document_count == 1
46
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(first_document)
47
+ yield(first_document)
48
+ end
49
+
50
+ self
51
+ end
52
+
53
+ def eager_load(docs)
54
+ associations = criteria.inclusions.map(&:name)
55
+ docs.each { |doc| Bullet::Detector::NPlusOneQuery.add_object_associations(doc, associations) }
56
+ Bullet::Detector::UnusedEagerLoading.add_eager_loadings(docs, associations)
57
+ origin_eager_load(docs)
58
+ end
59
+ end
60
+
61
+ ::Mongoid::Association::Accessors.class_eval do
62
+ alias_method :origin_get_relation, :get_relation
63
+
64
+ def get_relation(name, association, object, reload = false)
65
+ result = origin_get_relation(name, association, object, reload)
66
+ Bullet::Detector::NPlusOneQuery.call_association(self, name) unless association.embedded?
67
+ result
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -35,7 +35,11 @@ module Bullet
35
35
  end
36
36
 
37
37
  def include?(key, value)
38
- !@registry[key].nil? && @registry[key].include?(value)
38
+ key?(key) && @registry[key].include?(value)
39
+ end
40
+
41
+ def key?(key)
42
+ @registry.key?(key)
39
43
  end
40
44
  end
41
45
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bullet
4
- VERSION = '8.0.1'
4
+ VERSION = '8.0.3'
5
5
  end
data/lib/bullet.rb CHANGED
@@ -64,7 +64,7 @@ module Bullet
64
64
  ].freeze
65
65
 
66
66
  def enable=(enable)
67
- @enable = @n_plus_one_query_enable = @unused_eager_loading_enable = @counter_cache_enable = enable
67
+ @enable = enable
68
68
 
69
69
  if enable?
70
70
  reset_safelist
@@ -90,15 +90,15 @@ module Bullet
90
90
  end
91
91
 
92
92
  def n_plus_one_query_enable?
93
- enable? && !!@n_plus_one_query_enable
93
+ enable? && (@n_plus_one_query_enable.nil? ? true : @n_plus_one_query_enable)
94
94
  end
95
95
 
96
96
  def unused_eager_loading_enable?
97
- enable? && !!@unused_eager_loading_enable
97
+ enable? && (@unused_eager_loading_enable.nil? ? true : @unused_eager_loading_enable)
98
98
  end
99
99
 
100
100
  def counter_cache_enable?
101
- enable? && !!@counter_cache_enable
101
+ enable? && (@counter_cache_enable.nil? ? true : @counter_cache_enable)
102
102
  end
103
103
 
104
104
  def stacktrace_includes
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bullet
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.0.1
4
+ version: 8.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Huang
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-02-10 00:00:00.000000000 Z
10
+ date: 2025-04-04 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: activesupport
@@ -75,6 +75,7 @@ files:
75
75
  - lib/bullet/mongoid6x.rb
76
76
  - lib/bullet/mongoid7x.rb
77
77
  - lib/bullet/mongoid8x.rb
78
+ - lib/bullet/mongoid9x.rb
78
79
  - lib/bullet/notification.rb
79
80
  - lib/bullet/notification/base.rb
80
81
  - lib/bullet/notification/counter_cache.rb