mongoid 9.0.4 → 9.0.6
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 +4 -4
- data/lib/mongoid/association/eager_loadable.rb +3 -0
- data/lib/mongoid/association/referenced/has_many/enumerable.rb +21 -4
- data/lib/mongoid/interceptable.rb +6 -5
- data/lib/mongoid/timestamps/created.rb +8 -1
- data/lib/mongoid/traversable.rb +12 -0
- data/lib/mongoid/validatable/associated.rb +1 -1
- data/lib/mongoid/version.rb +1 -1
- data/spec/integration/app_spec.rb +4 -0
- data/spec/mongoid/association/eager_spec.rb +24 -2
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +28 -37
- data/spec/mongoid/association_spec.rb +60 -0
- data/spec/mongoid/interceptable_spec.rb +78 -0
- data/spec/mongoid/interceptable_spec_models.rb +39 -115
- data/spec/mongoid/timestamps/created_spec.rb +23 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: de63ddee828740cd1ba5832d931cd2c9731f19c1435076527533fb7856b48f8c
|
4
|
+
data.tar.gz: 4cfa7d1e9f00ec0fe57c7709c7147f9b214375de3e402d5a468e03cf6e61af40
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4542042a79b3a3162acd38d28898cd0755128b0a209d33e3ecf18b98d12e7ab1d220045156164ec235672cff337fc2d2a53a5779b37b601e9d903481e2793236
|
7
|
+
data.tar.gz: 5bd06c74d154e09f12120d81813e6e2a1380d141cd3613350355e30e0ded7fc9774dd7dfb1ca335e00a7ad0c512e4a019e0df51bec7cb06e334cead745dd098c
|
@@ -42,6 +42,9 @@ module Mongoid
|
|
42
42
|
docs_map = {}
|
43
43
|
queue = [ klass.to_s ]
|
44
44
|
|
45
|
+
# account for single-collection inheritance
|
46
|
+
queue.push(klass.root_class.to_s) if klass != klass.root_class
|
47
|
+
|
45
48
|
while klass = queue.shift
|
46
49
|
if as = assoc_map.delete(klass)
|
47
50
|
as.each do |assoc|
|
@@ -419,11 +419,28 @@ module Mongoid
|
|
419
419
|
#
|
420
420
|
# @return [ Integer ] The size of the enumerable.
|
421
421
|
def size
|
422
|
-
|
423
|
-
|
424
|
-
|
422
|
+
# If _unloaded is present, then it will match the set of documents
|
423
|
+
# that belong to this association, which have already been persisted
|
424
|
+
# to the database. This set of documents must be considered when
|
425
|
+
# computing the size of the association, along with anything that has
|
426
|
+
# since been added.
|
427
|
+
if _unloaded
|
428
|
+
if _added.any?
|
429
|
+
# Note that _added may include records that _unloaded already
|
430
|
+
# matches. This is the case if the association is assigned an array
|
431
|
+
# of items and some of them were already elements of the association.
|
432
|
+
#
|
433
|
+
# we need to thus make sure _unloaded.count excludes any elements
|
434
|
+
# that already exist in _added.
|
435
|
+
|
436
|
+
count = _unloaded.not(:_id.in => _added.values.map(&:id)).count
|
437
|
+
count + _added.values.count
|
438
|
+
else
|
439
|
+
_unloaded.count
|
440
|
+
end
|
441
|
+
|
425
442
|
else
|
426
|
-
count + _added.
|
443
|
+
_loaded.count + _added.count
|
427
444
|
end
|
428
445
|
end
|
429
446
|
|
@@ -152,9 +152,13 @@ module Mongoid
|
|
152
152
|
# @api private
|
153
153
|
def _mongoid_run_child_callbacks(kind, children: nil, &block)
|
154
154
|
if Mongoid::Config.around_callbacks_for_embeds
|
155
|
-
_mongoid_run_child_callbacks_with_around(kind,
|
155
|
+
_mongoid_run_child_callbacks_with_around(kind,
|
156
|
+
children: children,
|
157
|
+
&block)
|
156
158
|
else
|
157
|
-
_mongoid_run_child_callbacks_without_around(kind,
|
159
|
+
_mongoid_run_child_callbacks_without_around(kind,
|
160
|
+
children: children,
|
161
|
+
&block)
|
158
162
|
end
|
159
163
|
end
|
160
164
|
|
@@ -235,9 +239,6 @@ module Mongoid
|
|
235
239
|
return false if env.halted
|
236
240
|
env.value = !env.halted
|
237
241
|
callback_list << [next_sequence, env]
|
238
|
-
if (grandchildren = child.send(:cascadable_children, kind))
|
239
|
-
_mongoid_run_child_before_callbacks(kind, children: grandchildren, callback_list: callback_list)
|
240
|
-
end
|
241
242
|
end
|
242
243
|
callback_list
|
243
244
|
end
|
@@ -23,13 +23,20 @@ module Mongoid
|
|
23
23
|
# @example Set the created at time.
|
24
24
|
# person.set_created_at
|
25
25
|
def set_created_at
|
26
|
-
if
|
26
|
+
if able_to_set_created_at?
|
27
27
|
now = Time.current
|
28
28
|
self.updated_at = now if is_a?(Updated) && !updated_at_changed?
|
29
29
|
self.created_at = now
|
30
30
|
end
|
31
31
|
clear_timeless_option
|
32
32
|
end
|
33
|
+
|
34
|
+
# Is the created timestamp able to be set?
|
35
|
+
#
|
36
|
+
# @return [ true, false ] If the timestamp can be set.
|
37
|
+
def able_to_set_created_at?
|
38
|
+
!frozen? && !timeless? && !created_at
|
39
|
+
end
|
33
40
|
end
|
34
41
|
end
|
35
42
|
end
|
data/lib/mongoid/traversable.rb
CHANGED
@@ -44,6 +44,18 @@ module Mongoid
|
|
44
44
|
!!(superclass < Mongoid::Document)
|
45
45
|
end
|
46
46
|
|
47
|
+
# Returns the root class of the STI tree that the current
|
48
|
+
# class participates in. If the class is not an STI subclass, this
|
49
|
+
# returns the class itself.
|
50
|
+
#
|
51
|
+
# @return [ Mongoid::Document ] the root of the STI tree
|
52
|
+
def root_class
|
53
|
+
root = self
|
54
|
+
root = root.superclass while root.hereditary?
|
55
|
+
|
56
|
+
root
|
57
|
+
end
|
58
|
+
|
47
59
|
# When inheriting, we want to copy the fields from the parent class and
|
48
60
|
# set the on the child to start, mimicking the behavior of the old
|
49
61
|
# class_inheritable_accessor that was deprecated in Rails edge.
|
@@ -74,7 +74,7 @@ module Mongoid
|
|
74
74
|
# use map.all? instead of just all?, because all? will do short-circuit
|
75
75
|
# evaluation and terminate on the first failed validation.
|
76
76
|
list.map do |value|
|
77
|
-
if value && !value.flagged_for_destroy?
|
77
|
+
if value && !value.flagged_for_destroy?
|
78
78
|
value.validated? ? true : value.valid?
|
79
79
|
else
|
80
80
|
true
|
data/lib/mongoid/version.rb
CHANGED
@@ -26,6 +26,10 @@ describe 'Mongoid application tests' do
|
|
26
26
|
skip 'Set APP_TESTS=1 in environment to run application tests'
|
27
27
|
end
|
28
28
|
|
29
|
+
if SpecConfig.instance.rails_version < '7.1'
|
30
|
+
skip 'App tests require Rails > 7.0 (see https://stackoverflow.com/questions/79360526)'
|
31
|
+
end
|
32
|
+
|
29
33
|
require 'fileutils'
|
30
34
|
require 'mrss/child_process_helper'
|
31
35
|
require 'open-uri'
|
@@ -15,14 +15,36 @@ describe Mongoid::Association::EagerLoadable do
|
|
15
15
|
Mongoid::Contextual::Mongo.new(criteria)
|
16
16
|
end
|
17
17
|
|
18
|
+
let(:association_host) { Account }
|
19
|
+
|
18
20
|
let(:inclusions) do
|
19
21
|
includes.map do |key|
|
20
|
-
|
22
|
+
association_host.reflect_on_association(key)
|
21
23
|
end
|
22
24
|
end
|
23
25
|
|
24
26
|
let(:doc) { criteria.first }
|
25
27
|
|
28
|
+
context 'when root is an STI subclass' do
|
29
|
+
# Driver has_one Vehicle
|
30
|
+
# Vehicle belongs_to Driver
|
31
|
+
# Truck is a Vehicle
|
32
|
+
|
33
|
+
before do
|
34
|
+
Driver.create!(vehicle: Truck.new)
|
35
|
+
end
|
36
|
+
|
37
|
+
let(:criteria) { Truck.all }
|
38
|
+
let(:includes) { %i[ driver ] }
|
39
|
+
let(:association_host) { Truck }
|
40
|
+
|
41
|
+
it 'preloads the driver' do
|
42
|
+
expect(doc.ivar(:driver)).to be false
|
43
|
+
context.preload(inclusions, [ doc ])
|
44
|
+
expect(doc.ivar(:driver)).to be == Driver.first
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
26
48
|
context "when belongs_to" do
|
27
49
|
|
28
50
|
let!(:account) do
|
@@ -43,7 +65,7 @@ describe Mongoid::Association::EagerLoadable do
|
|
43
65
|
it "preloads the parent" do
|
44
66
|
expect(doc.ivar(:person)).to be false
|
45
67
|
context.preload(inclusions, [doc])
|
46
|
-
expect(doc.ivar(:person)).to
|
68
|
+
expect(doc.ivar(:person)).to be == person
|
47
69
|
end
|
48
70
|
end
|
49
71
|
|
@@ -1756,43 +1756,6 @@ describe Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy do
|
|
1756
1756
|
end
|
1757
1757
|
end
|
1758
1758
|
|
1759
|
-
describe "#any?" do
|
1760
|
-
|
1761
|
-
let(:person) do
|
1762
|
-
Person.create!
|
1763
|
-
end
|
1764
|
-
|
1765
|
-
context "when nothing exists on the relation" do
|
1766
|
-
|
1767
|
-
context "when no document is added" do
|
1768
|
-
|
1769
|
-
let!(:sandwich) do
|
1770
|
-
Sandwich.create!
|
1771
|
-
end
|
1772
|
-
|
1773
|
-
it "returns false" do
|
1774
|
-
expect(sandwich.meats.any?).to be false
|
1775
|
-
end
|
1776
|
-
end
|
1777
|
-
|
1778
|
-
context "when the document is destroyed" do
|
1779
|
-
|
1780
|
-
before do
|
1781
|
-
Meat.create!
|
1782
|
-
end
|
1783
|
-
|
1784
|
-
let!(:sandwich) do
|
1785
|
-
Sandwich.create!
|
1786
|
-
end
|
1787
|
-
|
1788
|
-
it "returns false" do
|
1789
|
-
sandwich.destroy
|
1790
|
-
expect(sandwich.meats.any?).to be false
|
1791
|
-
end
|
1792
|
-
end
|
1793
|
-
end
|
1794
|
-
end
|
1795
|
-
|
1796
1759
|
context "when documents have been persisted" do
|
1797
1760
|
|
1798
1761
|
let!(:preference) do
|
@@ -3041,6 +3004,34 @@ describe Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy do
|
|
3041
3004
|
end
|
3042
3005
|
end
|
3043
3006
|
|
3007
|
+
# MONGOID-5844
|
3008
|
+
#
|
3009
|
+
# Specifically, this tests the case where the association is
|
3010
|
+
# initialized with a single element (so that Proxy#push does not take
|
3011
|
+
# the `concat` route), which causes `reset_unloaded` to be called, which
|
3012
|
+
# sets the `_unloaded` Criteria object to match only the specific element
|
3013
|
+
# that was given.
|
3014
|
+
#
|
3015
|
+
# The issue now is that when the events list is updated to be both events,
|
3016
|
+
# _unloaded matches one of them already, and the other has previously been
|
3017
|
+
# persisted so `new_record?` won't match it. We need to make sure the
|
3018
|
+
# `#size` logic properly accounts for this case.
|
3019
|
+
context 'when documents have been previously persisted' do
|
3020
|
+
let(:person1) { Person.create! }
|
3021
|
+
let(:person2) { Person.create! }
|
3022
|
+
let(:event1) { Event.create!(administrators: [ person1 ]) }
|
3023
|
+
let(:event2) { Event.create!(administrators: [ person2 ]) }
|
3024
|
+
|
3025
|
+
before do
|
3026
|
+
person1.administrated_events = [ event1, event2 ]
|
3027
|
+
end
|
3028
|
+
|
3029
|
+
it 'returns the number of associated documents [MONGOID-5844]' do
|
3030
|
+
expect(person1.administrated_events.to_a.size).to eq(2)
|
3031
|
+
expect(person1.administrated_events.size).to eq(2)
|
3032
|
+
end
|
3033
|
+
end
|
3034
|
+
|
3044
3035
|
context "when documents have not been persisted" do
|
3045
3036
|
|
3046
3037
|
before do
|
@@ -115,6 +115,66 @@ describe Mongoid::Association do
|
|
115
115
|
expect(name).to_not be_an_embedded_many
|
116
116
|
end
|
117
117
|
end
|
118
|
+
|
119
|
+
context "when validation depends on association" do
|
120
|
+
before(:all) do
|
121
|
+
class Author
|
122
|
+
include Mongoid::Document
|
123
|
+
embeds_many :books, cascade_callbacks: true
|
124
|
+
field :condition, type: Boolean
|
125
|
+
end
|
126
|
+
|
127
|
+
class Book
|
128
|
+
include Mongoid::Document
|
129
|
+
embedded_in :author
|
130
|
+
validate :parent_condition_is_not_true
|
131
|
+
|
132
|
+
def parent_condition_is_not_true
|
133
|
+
return unless author&.condition
|
134
|
+
errors.add :base, "Author condition is true."
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
Author.delete_all
|
139
|
+
Book.delete_all
|
140
|
+
end
|
141
|
+
|
142
|
+
let(:author) { Author.new }
|
143
|
+
let(:book) { Book.new }
|
144
|
+
|
145
|
+
context "when author is not persisted" do
|
146
|
+
it "is valid without books" do
|
147
|
+
expect(author.valid?).to be true
|
148
|
+
end
|
149
|
+
|
150
|
+
it "is valid with a book" do
|
151
|
+
author.books << book
|
152
|
+
expect(author.valid?).to be true
|
153
|
+
end
|
154
|
+
|
155
|
+
it "is not valid when condition is true with a book" do
|
156
|
+
author.condition = true
|
157
|
+
author.books << book
|
158
|
+
expect(author.valid?).to be false
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
context "when author is persisted" do
|
163
|
+
before do
|
164
|
+
author.books << book
|
165
|
+
author.save
|
166
|
+
end
|
167
|
+
|
168
|
+
it "remains valid initially" do
|
169
|
+
expect(author.valid?).to be true
|
170
|
+
end
|
171
|
+
|
172
|
+
it "becomes invalid when condition is set to true" do
|
173
|
+
author.update_attributes(condition: true)
|
174
|
+
expect(author.valid?).to be false
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
118
178
|
end
|
119
179
|
|
120
180
|
describe "#embedded_one?" do
|
@@ -389,6 +389,84 @@ describe Mongoid::Interceptable do
|
|
389
389
|
end
|
390
390
|
end
|
391
391
|
end
|
392
|
+
|
393
|
+
context 'with embedded grandchildren' do
|
394
|
+
IS = InterceptableSpec
|
395
|
+
|
396
|
+
context 'when creating' do
|
397
|
+
let(:registry) { IS::CallbackRegistry.new(only: %i[ before_save ]) }
|
398
|
+
|
399
|
+
let(:expected_calls) do
|
400
|
+
[
|
401
|
+
# the parent
|
402
|
+
[ IS::CbParent, :before_save ],
|
403
|
+
|
404
|
+
# the immediate child of the parent
|
405
|
+
[ IS::CbCascadedNode, :before_save ],
|
406
|
+
|
407
|
+
# the grandchild of the parent
|
408
|
+
[ IS::CbCascadedNode, :before_save ],
|
409
|
+
]
|
410
|
+
end
|
411
|
+
|
412
|
+
let!(:parent) do
|
413
|
+
parent = IS::CbParent.new(registry)
|
414
|
+
child = IS::CbCascadedNode.new(registry)
|
415
|
+
grandchild = IS::CbCascadedNode.new(registry)
|
416
|
+
|
417
|
+
child.cb_cascaded_nodes = [ grandchild ]
|
418
|
+
parent.cb_cascaded_nodes = [ child ]
|
419
|
+
|
420
|
+
parent.tap(&:save)
|
421
|
+
end
|
422
|
+
|
423
|
+
it 'should cascade callbacks to grandchildren' do
|
424
|
+
expect(registry.calls).to be == expected_calls
|
425
|
+
end
|
426
|
+
end
|
427
|
+
|
428
|
+
context 'when updating' do
|
429
|
+
let(:registry) { IS::CallbackRegistry.new(only: %i[ before_update ]) }
|
430
|
+
|
431
|
+
let(:expected_calls) do
|
432
|
+
[
|
433
|
+
# the parent
|
434
|
+
[ IS::CbParent, :before_update ],
|
435
|
+
|
436
|
+
# the immediate child of the parent
|
437
|
+
[ IS::CbCascadedNode, :before_update ],
|
438
|
+
|
439
|
+
# the grandchild of the parent
|
440
|
+
[ IS::CbCascadedNode, :before_update ],
|
441
|
+
]
|
442
|
+
end
|
443
|
+
|
444
|
+
let!(:parent) do
|
445
|
+
parent = IS::CbParent.new(nil)
|
446
|
+
child = IS::CbCascadedNode.new(nil)
|
447
|
+
grandchild = IS::CbCascadedNode.new(nil)
|
448
|
+
|
449
|
+
child.cb_cascaded_nodes = [ grandchild ]
|
450
|
+
parent.cb_cascaded_nodes = [ child ]
|
451
|
+
|
452
|
+
parent.save
|
453
|
+
|
454
|
+
parent.callback_registry = registry
|
455
|
+
child.callback_registry = registry
|
456
|
+
grandchild.callback_registry = registry
|
457
|
+
|
458
|
+
parent.name = 'updated'
|
459
|
+
child.name = 'updated'
|
460
|
+
grandchild.name = 'updated'
|
461
|
+
|
462
|
+
parent.tap(&:save)
|
463
|
+
end
|
464
|
+
|
465
|
+
it 'should cascade callbacks to grandchildren' do
|
466
|
+
expect(registry.calls).to be == expected_calls
|
467
|
+
end
|
468
|
+
end
|
469
|
+
end
|
392
470
|
end
|
393
471
|
|
394
472
|
describe ".before_destroy" do
|
@@ -1,11 +1,13 @@
|
|
1
1
|
# rubocop:todo all
|
2
2
|
module InterceptableSpec
|
3
3
|
class CallbackRegistry
|
4
|
-
def initialize
|
4
|
+
def initialize(only: [])
|
5
5
|
@calls = []
|
6
|
+
@only = only
|
6
7
|
end
|
7
8
|
|
8
9
|
def record_call(cls, cb)
|
10
|
+
return unless @only.empty? || @only.any? { |pat| pat == cb }
|
9
11
|
@calls << [cls, cb]
|
10
12
|
end
|
11
13
|
|
@@ -16,6 +18,8 @@ module InterceptableSpec
|
|
16
18
|
extend ActiveSupport::Concern
|
17
19
|
|
18
20
|
included do
|
21
|
+
field :name, type: String
|
22
|
+
|
19
23
|
%i(
|
20
24
|
validation save create update
|
21
25
|
).each do |what|
|
@@ -35,199 +39,110 @@ module InterceptableSpec
|
|
35
39
|
end
|
36
40
|
end
|
37
41
|
end
|
38
|
-
end
|
39
|
-
|
40
|
-
class CbHasOneParent
|
41
|
-
include Mongoid::Document
|
42
42
|
|
43
|
-
|
43
|
+
attr_accessor :callback_registry
|
44
44
|
|
45
|
-
def initialize(callback_registry)
|
45
|
+
def initialize(callback_registry, *args, **kwargs)
|
46
46
|
@callback_registry = callback_registry
|
47
|
-
super()
|
47
|
+
super(*args, **kwargs)
|
48
48
|
end
|
49
|
+
end
|
49
50
|
|
50
|
-
|
51
|
-
|
51
|
+
module RootInsertable
|
52
52
|
def insert_as_root
|
53
53
|
@callback_registry&.record_call(self.class, :insert_into_database)
|
54
54
|
super
|
55
55
|
end
|
56
|
+
end
|
56
57
|
|
58
|
+
class CbHasOneParent
|
59
|
+
include Mongoid::Document
|
57
60
|
include CallbackTracking
|
61
|
+
include RootInsertable
|
62
|
+
|
63
|
+
has_one :child, autosave: true, class_name: "CbHasOneChild", inverse_of: :parent
|
58
64
|
end
|
59
65
|
|
60
66
|
class CbHasOneChild
|
61
67
|
include Mongoid::Document
|
68
|
+
include CallbackTracking
|
62
69
|
|
63
70
|
belongs_to :parent, class_name: "CbHasOneParent", inverse_of: :child
|
64
|
-
|
65
|
-
def initialize(callback_registry)
|
66
|
-
@callback_registry = callback_registry
|
67
|
-
super()
|
68
|
-
end
|
69
|
-
|
70
|
-
attr_accessor :callback_registry
|
71
|
-
|
72
|
-
include CallbackTracking
|
73
71
|
end
|
74
72
|
|
75
73
|
class CbHasManyParent
|
76
74
|
include Mongoid::Document
|
75
|
+
include CallbackTracking
|
76
|
+
include RootInsertable
|
77
77
|
|
78
78
|
has_many :children, autosave: true, class_name: "CbHasManyChild", inverse_of: :parent
|
79
|
-
|
80
|
-
def initialize(callback_registry)
|
81
|
-
@callback_registry = callback_registry
|
82
|
-
super()
|
83
|
-
end
|
84
|
-
|
85
|
-
attr_accessor :callback_registry
|
86
|
-
|
87
|
-
def insert_as_root
|
88
|
-
@callback_registry&.record_call(self.class, :insert_into_database)
|
89
|
-
super
|
90
|
-
end
|
91
|
-
|
92
|
-
include CallbackTracking
|
93
79
|
end
|
94
80
|
|
95
81
|
class CbHasManyChild
|
96
82
|
include Mongoid::Document
|
83
|
+
include CallbackTracking
|
97
84
|
|
98
85
|
belongs_to :parent, class_name: "CbHasManyParent", inverse_of: :children
|
99
|
-
|
100
|
-
def initialize(callback_registry)
|
101
|
-
@callback_registry = callback_registry
|
102
|
-
super()
|
103
|
-
end
|
104
|
-
|
105
|
-
attr_accessor :callback_registry
|
106
|
-
|
107
|
-
include CallbackTracking
|
108
86
|
end
|
109
87
|
|
110
88
|
class CbEmbedsOneParent
|
111
89
|
include Mongoid::Document
|
90
|
+
include CallbackTracking
|
91
|
+
include RootInsertable
|
112
92
|
|
113
93
|
field :name
|
114
94
|
|
115
95
|
embeds_one :child, cascade_callbacks: true, class_name: "CbEmbedsOneChild", inverse_of: :parent
|
116
|
-
|
117
|
-
def initialize(callback_registry)
|
118
|
-
@callback_registry = callback_registry
|
119
|
-
super()
|
120
|
-
end
|
121
|
-
|
122
|
-
attr_accessor :callback_registry
|
123
|
-
|
124
|
-
def insert_as_root
|
125
|
-
@callback_registry&.record_call(self.class, :insert_into_database)
|
126
|
-
super
|
127
|
-
end
|
128
|
-
|
129
|
-
include CallbackTracking
|
130
96
|
end
|
131
97
|
|
132
98
|
class CbEmbedsOneChild
|
133
99
|
include Mongoid::Document
|
100
|
+
include CallbackTracking
|
134
101
|
|
135
102
|
field :age
|
136
103
|
|
137
104
|
embedded_in :parent, class_name: "CbEmbedsOneParent", inverse_of: :child
|
138
|
-
|
139
|
-
def initialize(callback_registry)
|
140
|
-
@callback_registry = callback_registry
|
141
|
-
super()
|
142
|
-
end
|
143
|
-
|
144
|
-
attr_accessor :callback_registry
|
145
|
-
|
146
|
-
include CallbackTracking
|
147
105
|
end
|
148
106
|
|
149
107
|
class CbEmbedsManyParent
|
150
108
|
include Mongoid::Document
|
109
|
+
include CallbackTracking
|
110
|
+
include RootInsertable
|
151
111
|
|
152
112
|
embeds_many :children, cascade_callbacks: true, class_name: "CbEmbedsManyChild", inverse_of: :parent
|
153
|
-
|
154
|
-
def initialize(callback_registry)
|
155
|
-
@callback_registry = callback_registry
|
156
|
-
super()
|
157
|
-
end
|
158
|
-
|
159
|
-
attr_accessor :callback_registry
|
160
|
-
|
161
|
-
def insert_as_root
|
162
|
-
@callback_registry&.record_call(self.class, :insert_into_database)
|
163
|
-
super
|
164
|
-
end
|
165
|
-
|
166
|
-
include CallbackTracking
|
167
113
|
end
|
168
114
|
|
169
115
|
class CbEmbedsManyChild
|
170
116
|
include Mongoid::Document
|
117
|
+
include CallbackTracking
|
171
118
|
|
172
119
|
embedded_in :parent, class_name: "CbEmbedsManyParent", inverse_of: :children
|
173
|
-
|
174
|
-
def initialize(callback_registry)
|
175
|
-
@callback_registry = callback_registry
|
176
|
-
super()
|
177
|
-
end
|
178
|
-
|
179
|
-
attr_accessor :callback_registry
|
180
|
-
|
181
|
-
include CallbackTracking
|
182
120
|
end
|
183
121
|
|
184
122
|
class CbParent
|
185
123
|
include Mongoid::Document
|
186
|
-
|
187
|
-
def initialize(callback_registry)
|
188
|
-
@callback_registry = callback_registry
|
189
|
-
super()
|
190
|
-
end
|
191
|
-
|
192
|
-
attr_accessor :callback_registry
|
124
|
+
include CallbackTracking
|
193
125
|
|
194
126
|
embeds_many :cb_children
|
195
127
|
embeds_many :cb_cascaded_children, cascade_callbacks: true
|
196
|
-
|
197
|
-
include CallbackTracking
|
128
|
+
embeds_many :cb_cascaded_nodes, cascade_callbacks: true, as: :parent
|
198
129
|
end
|
199
130
|
|
200
131
|
class CbChild
|
201
132
|
include Mongoid::Document
|
133
|
+
include CallbackTracking
|
202
134
|
|
203
135
|
embedded_in :cb_parent
|
204
|
-
|
205
|
-
def initialize(callback_registry, options)
|
206
|
-
@callback_registry = callback_registry
|
207
|
-
super(options)
|
208
|
-
end
|
209
|
-
|
210
|
-
attr_accessor :callback_registry
|
211
|
-
|
212
|
-
include CallbackTracking
|
213
136
|
end
|
214
137
|
|
215
138
|
class CbCascadedChild
|
216
139
|
include Mongoid::Document
|
140
|
+
include CallbackTracking
|
217
141
|
|
218
142
|
embedded_in :cb_parent
|
219
143
|
|
220
|
-
def initialize(callback_registry, options)
|
221
|
-
@callback_registry = callback_registry
|
222
|
-
super(options)
|
223
|
-
end
|
224
|
-
|
225
|
-
attr_accessor :callback_registry
|
226
|
-
|
227
144
|
before_save :test_mongoid_state
|
228
145
|
|
229
|
-
include CallbackTracking
|
230
|
-
|
231
146
|
private
|
232
147
|
|
233
148
|
# Helps test that cascading child callbacks have access to the Mongoid
|
@@ -238,6 +153,15 @@ module InterceptableSpec
|
|
238
153
|
Mongoid::Threaded.stack('interceptable').push(self)
|
239
154
|
end
|
240
155
|
end
|
156
|
+
|
157
|
+
class CbCascadedNode
|
158
|
+
include Mongoid::Document
|
159
|
+
include CallbackTracking
|
160
|
+
|
161
|
+
embedded_in :parent, polymorphic: true
|
162
|
+
|
163
|
+
embeds_many :cb_cascaded_nodes, cascade_callbacks: true, as: :parent
|
164
|
+
end
|
241
165
|
end
|
242
166
|
|
243
167
|
class InterceptableBand
|
@@ -44,4 +44,27 @@ describe Mongoid::Timestamps::Created do
|
|
44
44
|
expect(quiz.created_at).to be_within(10).of(Time.now.utc)
|
45
45
|
end
|
46
46
|
end
|
47
|
+
|
48
|
+
context "when the document is destroyed" do
|
49
|
+
let(:book) do
|
50
|
+
Book.create!
|
51
|
+
end
|
52
|
+
|
53
|
+
before do
|
54
|
+
Cover.before_save do
|
55
|
+
destroy if title == "delete me"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
after do
|
60
|
+
Cover.reset_callbacks(:save)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "does not set the created_at timestamp" do
|
64
|
+
book.covers << Cover.new(title: "delete me")
|
65
|
+
expect {
|
66
|
+
book.save
|
67
|
+
}.not_to raise_error
|
68
|
+
end
|
69
|
+
end
|
47
70
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 9.0.
|
4
|
+
version: 9.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- The MongoDB Ruby Team
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-
|
10
|
+
date: 2025-02-24 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: activemodel
|
@@ -1202,7 +1202,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
1202
1202
|
- !ruby/object:Gem::Version
|
1203
1203
|
version: 1.3.6
|
1204
1204
|
requirements: []
|
1205
|
-
rubygems_version: 3.6.
|
1205
|
+
rubygems_version: 3.6.5
|
1206
1206
|
specification_version: 4
|
1207
1207
|
summary: Elegant Persistence in Ruby for MongoDB.
|
1208
1208
|
test_files:
|