mongoid 8.0.8 → 8.0.10
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/Rakefile +65 -41
- data/lib/mongoid/association/accessors.rb +5 -1
- data/lib/mongoid/association/eager_loadable.rb +3 -0
- data/lib/mongoid/association/referenced/has_many/enumerable.rb +21 -4
- data/lib/mongoid/config.rb +10 -0
- data/lib/mongoid/criteria/queryable/extensions/numeric.rb +15 -1
- data/lib/mongoid/document.rb +8 -1
- data/lib/mongoid/fields.rb +11 -6
- data/lib/mongoid/interceptable.rb +10 -8
- data/lib/mongoid/timestamps/created.rb +8 -1
- data/lib/mongoid/traversable.rb +12 -0
- data/lib/mongoid/validatable/associated.rb +6 -3
- data/lib/mongoid/version.rb +1 -1
- data/spec/integration/app_spec.rb +4 -0
- data/spec/integration/callbacks_models.rb +37 -0
- data/spec/integration/callbacks_spec.rb +27 -0
- data/spec/mongoid/association/eager_spec.rb +24 -2
- data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +4 -0
- 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/document_spec.rb +27 -0
- data/spec/mongoid/interceptable_spec.rb +100 -0
- data/spec/mongoid/interceptable_spec_models.rb +51 -111
- data/spec/mongoid/serializable_spec.rb +14 -14
- data/spec/mongoid/timestamps/created_spec.rb +23 -0
- data/spec/mongoid/validatable/associated_spec.rb +14 -4
- data/spec/support/models/book.rb +1 -0
- data/spec/support/models/cover.rb +10 -0
- metadata +6 -80
- checksums.yaml.gz.sig +0 -0
- data/spec/shared/LICENSE +0 -20
- data/spec/shared/bin/get-mongodb-download-url +0 -17
- data/spec/shared/bin/s3-copy +0 -45
- data/spec/shared/bin/s3-upload +0 -69
- data/spec/shared/lib/mrss/child_process_helper.rb +0 -80
- data/spec/shared/lib/mrss/cluster_config.rb +0 -231
- data/spec/shared/lib/mrss/constraints.rb +0 -378
- data/spec/shared/lib/mrss/docker_runner.rb +0 -298
- data/spec/shared/lib/mrss/eg_config_utils.rb +0 -51
- data/spec/shared/lib/mrss/event_subscriber.rb +0 -210
- data/spec/shared/lib/mrss/lite_constraints.rb +0 -238
- data/spec/shared/lib/mrss/server_version_registry.rb +0 -113
- data/spec/shared/lib/mrss/session_registry.rb +0 -69
- data/spec/shared/lib/mrss/session_registry_legacy.rb +0 -60
- data/spec/shared/lib/mrss/spec_organizer.rb +0 -179
- data/spec/shared/lib/mrss/utils.rb +0 -37
- data/spec/shared/share/Dockerfile.erb +0 -321
- data/spec/shared/share/haproxy-1.conf +0 -16
- data/spec/shared/share/haproxy-2.conf +0 -17
- data/spec/shared/shlib/config.sh +0 -27
- data/spec/shared/shlib/distro.sh +0 -74
- data/spec/shared/shlib/server.sh +0 -416
- data/spec/shared/shlib/set_env.sh +0 -169
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -0
@@ -100,6 +100,66 @@ describe Mongoid::Association do
|
|
100
100
|
expect(name).to_not be_an_embedded_many
|
101
101
|
end
|
102
102
|
end
|
103
|
+
|
104
|
+
context "when validation depends on association" do
|
105
|
+
before(:all) do
|
106
|
+
class Author
|
107
|
+
include Mongoid::Document
|
108
|
+
embeds_many :books, cascade_callbacks: true
|
109
|
+
field :condition, type: Boolean
|
110
|
+
end
|
111
|
+
|
112
|
+
class Book
|
113
|
+
include Mongoid::Document
|
114
|
+
embedded_in :author
|
115
|
+
validate :parent_condition_is_not_true
|
116
|
+
|
117
|
+
def parent_condition_is_not_true
|
118
|
+
return unless author&.condition
|
119
|
+
errors.add :base, "Author condition is true."
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
Author.delete_all
|
124
|
+
Book.delete_all
|
125
|
+
end
|
126
|
+
|
127
|
+
let(:author) { Author.new }
|
128
|
+
let(:book) { Book.new }
|
129
|
+
|
130
|
+
context "when author is not persisted" do
|
131
|
+
it "is valid without books" do
|
132
|
+
expect(author.valid?).to be true
|
133
|
+
end
|
134
|
+
|
135
|
+
it "is valid with a book" do
|
136
|
+
author.books << book
|
137
|
+
expect(author.valid?).to be true
|
138
|
+
end
|
139
|
+
|
140
|
+
it "is not valid when condition is true with a book" do
|
141
|
+
author.condition = true
|
142
|
+
author.books << book
|
143
|
+
expect(author.valid?).to be false
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
context "when author is persisted" do
|
148
|
+
before do
|
149
|
+
author.books << book
|
150
|
+
author.save
|
151
|
+
end
|
152
|
+
|
153
|
+
it "remains valid initially" do
|
154
|
+
expect(author.valid?).to be true
|
155
|
+
end
|
156
|
+
|
157
|
+
it "becomes invalid when condition is set to true" do
|
158
|
+
author.update_attributes(condition: true)
|
159
|
+
expect(author.valid?).to be false
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
103
163
|
end
|
104
164
|
|
105
165
|
describe "#embedded_one?" do
|
@@ -591,6 +591,33 @@ describe Mongoid::Document do
|
|
591
591
|
expect(person.as_document["addresses"].first).to have_key(:locations)
|
592
592
|
end
|
593
593
|
|
594
|
+
context 'when modifying the returned object' do
|
595
|
+
let(:record) do
|
596
|
+
RootCategory.create(categories: [{ name: 'tests' }]).reload
|
597
|
+
end
|
598
|
+
|
599
|
+
shared_examples_for 'an object with protected internal state' do
|
600
|
+
it 'does not expose internal state' do
|
601
|
+
before_change = record.as_document.dup
|
602
|
+
record.categories.first.name = 'things'
|
603
|
+
after_change = record.as_document
|
604
|
+
expect(before_change['categories'].first['name']).not_to eq('things')
|
605
|
+
end
|
606
|
+
end
|
607
|
+
|
608
|
+
context 'when legacy_attributes is true' do
|
609
|
+
config_override :legacy_attributes, true
|
610
|
+
|
611
|
+
it_behaves_like 'an object with protected internal state'
|
612
|
+
end
|
613
|
+
|
614
|
+
context 'when legacy_attributes is false' do
|
615
|
+
config_override :legacy_attributes, false
|
616
|
+
|
617
|
+
it_behaves_like 'an object with protected internal state'
|
618
|
+
end
|
619
|
+
end
|
620
|
+
|
594
621
|
context "with relation define store_as option in embeded_many" do
|
595
622
|
|
596
623
|
let!(:phone) do
|
@@ -388,6 +388,86 @@ describe Mongoid::Interceptable do
|
|
388
388
|
end
|
389
389
|
end
|
390
390
|
end
|
391
|
+
|
392
|
+
context 'with embedded grandchildren' do
|
393
|
+
IS = InterceptableSpec
|
394
|
+
|
395
|
+
config_override :prevent_multiple_calls_of_embedded_callbacks, true
|
396
|
+
|
397
|
+
context 'when creating' do
|
398
|
+
let(:registry) { IS::CallbackRegistry.new(only: %i[ before_save ]) }
|
399
|
+
|
400
|
+
let(:expected_calls) do
|
401
|
+
[
|
402
|
+
# the parent
|
403
|
+
[ IS::CbParent, :before_save ],
|
404
|
+
|
405
|
+
# the immediate child of the parent
|
406
|
+
[ IS::CbCascadedNode, :before_save ],
|
407
|
+
|
408
|
+
# the grandchild of the parent
|
409
|
+
[ IS::CbCascadedNode, :before_save ],
|
410
|
+
]
|
411
|
+
end
|
412
|
+
|
413
|
+
let!(:parent) do
|
414
|
+
parent = IS::CbParent.new(registry)
|
415
|
+
child = IS::CbCascadedNode.new(registry)
|
416
|
+
grandchild = IS::CbCascadedNode.new(registry)
|
417
|
+
|
418
|
+
child.cb_cascaded_nodes = [ grandchild ]
|
419
|
+
parent.cb_cascaded_nodes = [ child ]
|
420
|
+
|
421
|
+
parent.tap(&:save)
|
422
|
+
end
|
423
|
+
|
424
|
+
it 'should cascade callbacks to grandchildren' do
|
425
|
+
expect(registry.calls).to be == expected_calls
|
426
|
+
end
|
427
|
+
end
|
428
|
+
|
429
|
+
context 'when updating' do
|
430
|
+
let(:registry) { IS::CallbackRegistry.new(only: %i[ before_update ]) }
|
431
|
+
|
432
|
+
let(:expected_calls) do
|
433
|
+
[
|
434
|
+
# the parent
|
435
|
+
[ IS::CbParent, :before_update ],
|
436
|
+
|
437
|
+
# the immediate child of the parent
|
438
|
+
[ IS::CbCascadedNode, :before_update ],
|
439
|
+
|
440
|
+
# the grandchild of the parent
|
441
|
+
[ IS::CbCascadedNode, :before_update ],
|
442
|
+
]
|
443
|
+
end
|
444
|
+
|
445
|
+
let!(:parent) do
|
446
|
+
parent = IS::CbParent.new(nil)
|
447
|
+
child = IS::CbCascadedNode.new(nil)
|
448
|
+
grandchild = IS::CbCascadedNode.new(nil)
|
449
|
+
|
450
|
+
child.cb_cascaded_nodes = [ grandchild ]
|
451
|
+
parent.cb_cascaded_nodes = [ child ]
|
452
|
+
|
453
|
+
parent.save
|
454
|
+
|
455
|
+
parent.callback_registry = registry
|
456
|
+
child.callback_registry = registry
|
457
|
+
grandchild.callback_registry = registry
|
458
|
+
|
459
|
+
parent.name = 'updated'
|
460
|
+
child.name = 'updated'
|
461
|
+
grandchild.name = 'updated'
|
462
|
+
|
463
|
+
parent.tap(&:save)
|
464
|
+
end
|
465
|
+
|
466
|
+
it 'should cascade callbacks to grandchildren' do
|
467
|
+
expect(registry.calls).to be == expected_calls
|
468
|
+
end
|
469
|
+
end
|
470
|
+
end
|
391
471
|
end
|
392
472
|
|
393
473
|
describe ".before_destroy" do
|
@@ -578,6 +658,26 @@ describe Mongoid::Interceptable do
|
|
578
658
|
band.notes.push(note)
|
579
659
|
record.notes.push(note)
|
580
660
|
end
|
661
|
+
|
662
|
+
context "when saving the root" do
|
663
|
+
context 'with prevent_multiple_calls_of_embedded_callbacks enabled' do
|
664
|
+
config_override :prevent_multiple_calls_of_embedded_callbacks, true
|
665
|
+
|
666
|
+
it "executes the callbacks only once for each document" do
|
667
|
+
expect(note).to receive(:update_saved).once
|
668
|
+
band.save!
|
669
|
+
end
|
670
|
+
end
|
671
|
+
|
672
|
+
context 'with prevent_multiple_calls_of_embedded_callbacks disabled' do
|
673
|
+
config_override :prevent_multiple_calls_of_embedded_callbacks, false
|
674
|
+
|
675
|
+
it "executes the callbacks once for each ember" do
|
676
|
+
expect(note).to receive(:update_saved).twice
|
677
|
+
band.save!
|
678
|
+
end
|
679
|
+
end
|
680
|
+
end
|
581
681
|
end
|
582
682
|
end
|
583
683
|
|
@@ -1,13 +1,19 @@
|
|
1
1
|
module InterceptableSpec
|
2
2
|
class CallbackRegistry
|
3
|
-
def initialize
|
3
|
+
def initialize(only: [])
|
4
4
|
@calls = []
|
5
|
+
@only = only
|
5
6
|
end
|
6
7
|
|
7
8
|
def record_call(cls, cb)
|
9
|
+
return unless @only.empty? || @only.any? { |pat| pat == cb }
|
8
10
|
@calls << [cls, cb]
|
9
11
|
end
|
10
12
|
|
13
|
+
def reset!
|
14
|
+
@calls.clear
|
15
|
+
end
|
16
|
+
|
11
17
|
attr_reader :calls
|
12
18
|
end
|
13
19
|
|
@@ -15,6 +21,8 @@ module InterceptableSpec
|
|
15
21
|
extend ActiveSupport::Concern
|
16
22
|
|
17
23
|
included do
|
24
|
+
field :name, type: String
|
25
|
+
|
18
26
|
%i(
|
19
27
|
validation save create update
|
20
28
|
).each do |what|
|
@@ -34,196 +42,128 @@ module InterceptableSpec
|
|
34
42
|
end
|
35
43
|
end
|
36
44
|
end
|
37
|
-
end
|
38
45
|
|
39
|
-
|
40
|
-
include Mongoid::Document
|
41
|
-
|
42
|
-
has_one :child, autosave: true, class_name: "CbHasOneChild", inverse_of: :parent
|
46
|
+
attr_accessor :callback_registry
|
43
47
|
|
44
|
-
def initialize(callback_registry)
|
48
|
+
def initialize(callback_registry, *args, **kwargs)
|
45
49
|
@callback_registry = callback_registry
|
46
|
-
super()
|
50
|
+
super(*args, **kwargs)
|
47
51
|
end
|
52
|
+
end
|
48
53
|
|
49
|
-
|
50
|
-
|
54
|
+
module RootInsertable
|
51
55
|
def insert_as_root
|
52
56
|
@callback_registry&.record_call(self.class, :insert_into_database)
|
53
57
|
super
|
54
58
|
end
|
59
|
+
end
|
55
60
|
|
61
|
+
class CbHasOneParent
|
62
|
+
include Mongoid::Document
|
56
63
|
include CallbackTracking
|
64
|
+
include RootInsertable
|
65
|
+
|
66
|
+
has_one :child, autosave: true, class_name: "CbHasOneChild", inverse_of: :parent
|
57
67
|
end
|
58
68
|
|
59
69
|
class CbHasOneChild
|
60
70
|
include Mongoid::Document
|
71
|
+
include CallbackTracking
|
61
72
|
|
62
73
|
belongs_to :parent, class_name: "CbHasOneParent", inverse_of: :child
|
63
|
-
|
64
|
-
def initialize(callback_registry)
|
65
|
-
@callback_registry = callback_registry
|
66
|
-
super()
|
67
|
-
end
|
68
|
-
|
69
|
-
attr_accessor :callback_registry
|
70
|
-
|
71
|
-
include CallbackTracking
|
72
74
|
end
|
73
75
|
|
74
76
|
class CbHasManyParent
|
75
77
|
include Mongoid::Document
|
78
|
+
include CallbackTracking
|
79
|
+
include RootInsertable
|
76
80
|
|
77
81
|
has_many :children, autosave: true, class_name: "CbHasManyChild", inverse_of: :parent
|
78
|
-
|
79
|
-
def initialize(callback_registry)
|
80
|
-
@callback_registry = callback_registry
|
81
|
-
super()
|
82
|
-
end
|
83
|
-
|
84
|
-
attr_accessor :callback_registry
|
85
|
-
|
86
|
-
def insert_as_root
|
87
|
-
@callback_registry&.record_call(self.class, :insert_into_database)
|
88
|
-
super
|
89
|
-
end
|
90
|
-
|
91
|
-
include CallbackTracking
|
92
82
|
end
|
93
83
|
|
94
84
|
class CbHasManyChild
|
95
85
|
include Mongoid::Document
|
86
|
+
include CallbackTracking
|
96
87
|
|
97
88
|
belongs_to :parent, class_name: "CbHasManyParent", inverse_of: :children
|
98
|
-
|
99
|
-
def initialize(callback_registry)
|
100
|
-
@callback_registry = callback_registry
|
101
|
-
super()
|
102
|
-
end
|
103
|
-
|
104
|
-
attr_accessor :callback_registry
|
105
|
-
|
106
|
-
include CallbackTracking
|
107
89
|
end
|
108
90
|
|
109
91
|
class CbEmbedsOneParent
|
110
92
|
include Mongoid::Document
|
93
|
+
include CallbackTracking
|
94
|
+
include RootInsertable
|
111
95
|
|
112
96
|
field :name
|
113
97
|
|
114
98
|
embeds_one :child, cascade_callbacks: true, class_name: "CbEmbedsOneChild", inverse_of: :parent
|
115
|
-
|
116
|
-
def initialize(callback_registry)
|
117
|
-
@callback_registry = callback_registry
|
118
|
-
super()
|
119
|
-
end
|
120
|
-
|
121
|
-
attr_accessor :callback_registry
|
122
|
-
|
123
|
-
def insert_as_root
|
124
|
-
@callback_registry&.record_call(self.class, :insert_into_database)
|
125
|
-
super
|
126
|
-
end
|
127
|
-
|
128
|
-
include CallbackTracking
|
129
99
|
end
|
130
100
|
|
131
101
|
class CbEmbedsOneChild
|
132
102
|
include Mongoid::Document
|
103
|
+
include CallbackTracking
|
133
104
|
|
134
105
|
field :age
|
135
106
|
|
136
107
|
embedded_in :parent, class_name: "CbEmbedsOneParent", inverse_of: :child
|
137
|
-
|
138
|
-
def initialize(callback_registry)
|
139
|
-
@callback_registry = callback_registry
|
140
|
-
super()
|
141
|
-
end
|
142
|
-
|
143
|
-
attr_accessor :callback_registry
|
144
|
-
|
145
|
-
include CallbackTracking
|
146
108
|
end
|
147
109
|
|
148
110
|
class CbEmbedsManyParent
|
149
111
|
include Mongoid::Document
|
112
|
+
include CallbackTracking
|
113
|
+
include RootInsertable
|
150
114
|
|
151
115
|
embeds_many :children, cascade_callbacks: true, class_name: "CbEmbedsManyChild", inverse_of: :parent
|
152
|
-
|
153
|
-
def initialize(callback_registry)
|
154
|
-
@callback_registry = callback_registry
|
155
|
-
super()
|
156
|
-
end
|
157
|
-
|
158
|
-
attr_accessor :callback_registry
|
159
|
-
|
160
|
-
def insert_as_root
|
161
|
-
@callback_registry&.record_call(self.class, :insert_into_database)
|
162
|
-
super
|
163
|
-
end
|
164
|
-
|
165
|
-
include CallbackTracking
|
166
116
|
end
|
167
117
|
|
168
118
|
class CbEmbedsManyChild
|
169
119
|
include Mongoid::Document
|
120
|
+
include CallbackTracking
|
170
121
|
|
171
122
|
embedded_in :parent, class_name: "CbEmbedsManyParent", inverse_of: :children
|
172
|
-
|
173
|
-
def initialize(callback_registry)
|
174
|
-
@callback_registry = callback_registry
|
175
|
-
super()
|
176
|
-
end
|
177
|
-
|
178
|
-
attr_accessor :callback_registry
|
179
|
-
|
180
|
-
include CallbackTracking
|
181
123
|
end
|
182
124
|
|
183
125
|
class CbParent
|
184
126
|
include Mongoid::Document
|
185
|
-
|
186
|
-
def initialize(callback_registry)
|
187
|
-
@callback_registry = callback_registry
|
188
|
-
super()
|
189
|
-
end
|
190
|
-
|
191
|
-
attr_accessor :callback_registry
|
127
|
+
include CallbackTracking
|
192
128
|
|
193
129
|
embeds_many :cb_children
|
194
130
|
embeds_many :cb_cascaded_children, cascade_callbacks: true
|
195
|
-
|
196
|
-
include CallbackTracking
|
131
|
+
embeds_many :cb_cascaded_nodes, cascade_callbacks: true, as: :parent
|
197
132
|
end
|
198
133
|
|
199
134
|
class CbChild
|
200
135
|
include Mongoid::Document
|
136
|
+
include CallbackTracking
|
201
137
|
|
202
138
|
embedded_in :cb_parent
|
203
|
-
|
204
|
-
def initialize(callback_registry, options)
|
205
|
-
@callback_registry = callback_registry
|
206
|
-
super(options)
|
207
|
-
end
|
208
|
-
|
209
|
-
attr_accessor :callback_registry
|
210
|
-
|
211
|
-
include CallbackTracking
|
212
139
|
end
|
213
140
|
|
214
141
|
class CbCascadedChild
|
215
142
|
include Mongoid::Document
|
143
|
+
include CallbackTracking
|
216
144
|
|
217
145
|
embedded_in :cb_parent
|
218
146
|
|
219
|
-
|
220
|
-
@callback_registry = callback_registry
|
221
|
-
super(options)
|
222
|
-
end
|
147
|
+
before_save :test_mongoid_state
|
223
148
|
|
224
|
-
|
149
|
+
private
|
150
|
+
|
151
|
+
# Helps test that cascading child callbacks have access to the Mongoid
|
152
|
+
# state objects; if the implementation uses fiber-local (instead of truly
|
153
|
+
# thread-local) variables, the related tests will fail because the
|
154
|
+
# cascading child callbacks use fibers to linearize the recursion.
|
155
|
+
def test_mongoid_state
|
156
|
+
Mongoid::Threaded.stack('interceptable').push(self)
|
157
|
+
end
|
158
|
+
end
|
225
159
|
|
160
|
+
class CbCascadedNode
|
161
|
+
include Mongoid::Document
|
226
162
|
include CallbackTracking
|
163
|
+
|
164
|
+
embedded_in :parent, polymorphic: true
|
165
|
+
|
166
|
+
embeds_many :cb_cascaded_nodes, cascade_callbacks: true, as: :parent
|
227
167
|
end
|
228
168
|
end
|
229
169
|
|
@@ -528,13 +528,13 @@ describe Mongoid::Serializable do
|
|
528
528
|
end
|
529
529
|
|
530
530
|
it "includes the first relation" do
|
531
|
-
expect(relation_hash[0]).to include
|
532
|
-
{ "_id" => "kudamm", "street" => "Kudamm" }
|
531
|
+
expect(relation_hash[0]).to include(
|
532
|
+
{ "_id" => "kudamm", "street" => "Kudamm" })
|
533
533
|
end
|
534
534
|
|
535
535
|
it "includes the second relation" do
|
536
|
-
expect(relation_hash[1]).to include
|
537
|
-
{ "_id" => "tauentzienstr", "street" => "Tauentzienstr" }
|
536
|
+
expect(relation_hash[1]).to include(
|
537
|
+
{ "_id" => "tauentzienstr", "street" => "Tauentzienstr" })
|
538
538
|
end
|
539
539
|
end
|
540
540
|
|
@@ -545,13 +545,13 @@ describe Mongoid::Serializable do
|
|
545
545
|
end
|
546
546
|
|
547
547
|
it "includes the first relation" do
|
548
|
-
expect(relation_hash[0]).to include
|
549
|
-
{ "_id" => "kudamm", "street" => "Kudamm" }
|
548
|
+
expect(relation_hash[0]).to include(
|
549
|
+
{ "_id" => "kudamm", "street" => "Kudamm" })
|
550
550
|
end
|
551
551
|
|
552
552
|
it "includes the second relation" do
|
553
|
-
expect(relation_hash[1]).to include
|
554
|
-
{ "_id" => "tauentzienstr", "street" => "Tauentzienstr" }
|
553
|
+
expect(relation_hash[1]).to include(
|
554
|
+
{ "_id" => "tauentzienstr", "street" => "Tauentzienstr" })
|
555
555
|
end
|
556
556
|
end
|
557
557
|
|
@@ -670,8 +670,8 @@ describe Mongoid::Serializable do
|
|
670
670
|
end
|
671
671
|
|
672
672
|
it "includes the specified relation" do
|
673
|
-
expect(relation_hash).to include
|
674
|
-
{ "_id" => "
|
673
|
+
expect(relation_hash).to include(
|
674
|
+
{ "_id" => "Leo-Marvin", "first_name" => "Leo", "last_name" => "Marvin" })
|
675
675
|
end
|
676
676
|
end
|
677
677
|
|
@@ -682,8 +682,8 @@ describe Mongoid::Serializable do
|
|
682
682
|
end
|
683
683
|
|
684
684
|
it "includes the specified relation" do
|
685
|
-
expect(relation_hash).to include
|
686
|
-
{ "_id" => "
|
685
|
+
expect(relation_hash).to include(
|
686
|
+
{ "_id" => "Leo-Marvin", "first_name" => "Leo", "last_name" => "Marvin" })
|
687
687
|
end
|
688
688
|
end
|
689
689
|
|
@@ -694,8 +694,8 @@ describe Mongoid::Serializable do
|
|
694
694
|
end
|
695
695
|
|
696
696
|
it "includes the specified relation sans exceptions" do
|
697
|
-
expect(relation_hash).to include
|
698
|
-
{ "first_name" => "Leo", "last_name" => "Marvin" }
|
697
|
+
expect(relation_hash).to include(
|
698
|
+
{ "first_name" => "Leo", "last_name" => "Marvin" })
|
699
699
|
end
|
700
700
|
end
|
701
701
|
end
|
@@ -43,4 +43,27 @@ describe Mongoid::Timestamps::Created do
|
|
43
43
|
expect(quiz.created_at).to be_within(10).of(Time.now.utc)
|
44
44
|
end
|
45
45
|
end
|
46
|
+
|
47
|
+
context "when the document is destroyed" do
|
48
|
+
let(:book) do
|
49
|
+
Book.create!
|
50
|
+
end
|
51
|
+
|
52
|
+
before do
|
53
|
+
Cover.before_save do
|
54
|
+
destroy if title == "delete me"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
after do
|
59
|
+
Cover.reset_callbacks(:save)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "does not set the created_at timestamp" do
|
63
|
+
book.covers << Cover.new(title: "delete me")
|
64
|
+
expect {
|
65
|
+
book.save
|
66
|
+
}.not_to raise_error
|
67
|
+
end
|
68
|
+
end
|
46
69
|
end
|
@@ -37,12 +37,18 @@ describe Mongoid::Validatable::AssociatedValidator do
|
|
37
37
|
User.new(name: "test")
|
38
38
|
end
|
39
39
|
|
40
|
-
let(:
|
40
|
+
let(:description1) do
|
41
|
+
Description.new
|
42
|
+
end
|
43
|
+
|
44
|
+
let(:description2) do
|
41
45
|
Description.new
|
42
46
|
end
|
43
47
|
|
44
48
|
before do
|
45
|
-
user.descriptions <<
|
49
|
+
user.descriptions << description1
|
50
|
+
user.descriptions << description2
|
51
|
+
user.valid?
|
46
52
|
end
|
47
53
|
|
48
54
|
it "only validates the parent once" do
|
@@ -50,12 +56,16 @@ describe Mongoid::Validatable::AssociatedValidator do
|
|
50
56
|
end
|
51
57
|
|
52
58
|
it "adds the errors from the relation" do
|
53
|
-
user.valid?
|
54
59
|
expect(user.errors[:descriptions]).to_not be_nil
|
55
60
|
end
|
56
61
|
|
62
|
+
it 'reports all failed validations' do
|
63
|
+
errors = user.descriptions.flat_map { |d| d.errors[:details] }
|
64
|
+
expect(errors.length).to be == 2
|
65
|
+
end
|
66
|
+
|
57
67
|
it "only validates the child once" do
|
58
|
-
expect(
|
68
|
+
expect(description1).to_not be_valid
|
59
69
|
end
|
60
70
|
end
|
61
71
|
|
data/spec/support/models/book.rb
CHANGED