mongoid 9.0.6 → 9.0.8
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 +9 -9
- data/lib/mongoid/association/embedded/batchable.rb +11 -10
- data/lib/mongoid/association/embedded/embeds_many/proxy.rb +61 -0
- data/lib/mongoid/association/embedded/embeds_one/proxy.rb +1 -1
- data/lib/mongoid/association/nested/many.rb +2 -0
- data/lib/mongoid/association/nested/one.rb +1 -1
- data/lib/mongoid/association/referenced/has_many/proxy.rb +0 -4
- data/lib/mongoid/changeable.rb +10 -1
- data/lib/mongoid/clients/sessions.rb +3 -4
- data/lib/mongoid/config.rb +1 -1
- data/lib/mongoid/contextual/aggregable/mongo.rb +6 -1
- data/lib/mongoid/contextual/mongo.rb +1 -1
- data/lib/mongoid/railties/bson_object_id_serializer.rb +7 -0
- data/lib/mongoid/reloadable.rb +6 -0
- data/lib/mongoid/validatable/associated.rb +1 -1
- data/lib/mongoid/validatable/macros.rb +15 -0
- data/lib/mongoid/validatable/numericality.rb +19 -0
- data/lib/mongoid/validatable.rb +1 -0
- data/lib/mongoid/version.rb +5 -2
- data/spec/integration/app_spec.rb +6 -0
- data/spec/integration/associations/embeds_many_spec.rb +110 -0
- data/spec/integration/associations/embeds_one_spec.rb +25 -6
- data/spec/integration/associations/has_and_belongs_to_many_spec.rb +81 -0
- data/spec/integration/associations/has_many_spec.rb +56 -0
- data/spec/integration/associations/has_one_spec.rb +55 -3
- data/spec/mongoid/association/referenced/has_many_models.rb +24 -0
- data/spec/mongoid/association/referenced/has_one_models.rb +10 -2
- data/spec/mongoid/association_spec.rb +0 -60
- data/spec/mongoid/clients/transactions_spec.rb +162 -1
- data/spec/mongoid/clients/transactions_spec_models.rb +93 -0
- data/spec/mongoid/contextual/aggregable/mongo_spec.rb +33 -0
- data/spec/mongoid/contextual/mongo_spec.rb +6 -0
- data/spec/mongoid/reloadable_spec.rb +24 -0
- data/spec/mongoid/validatable/numericality_spec.rb +16 -0
- data/spec/shared/LICENSE +20 -0
- data/spec/shared/bin/get-mongodb-download-url +17 -0
- data/spec/shared/bin/s3-copy +45 -0
- data/spec/shared/bin/s3-upload +69 -0
- data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
- data/spec/shared/lib/mrss/cluster_config.rb +231 -0
- data/spec/shared/lib/mrss/constraints.rb +378 -0
- data/spec/shared/lib/mrss/docker_runner.rb +298 -0
- data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
- data/spec/shared/lib/mrss/event_subscriber.rb +210 -0
- data/spec/shared/lib/mrss/lite_constraints.rb +238 -0
- data/spec/shared/lib/mrss/release/candidate.rb +281 -0
- data/spec/shared/lib/mrss/release/product_data.rb +144 -0
- data/spec/shared/lib/mrss/server_version_registry.rb +113 -0
- data/spec/shared/lib/mrss/session_registry.rb +69 -0
- data/spec/shared/lib/mrss/session_registry_legacy.rb +60 -0
- data/spec/shared/lib/mrss/spec_organizer.rb +179 -0
- data/spec/shared/lib/mrss/utils.rb +37 -0
- data/spec/shared/lib/tasks/candidate.rake +64 -0
- data/spec/shared/share/Dockerfile.erb +251 -0
- data/spec/shared/share/haproxy-1.conf +16 -0
- data/spec/shared/share/haproxy-2.conf +17 -0
- data/spec/shared/shlib/config.sh +27 -0
- data/spec/shared/shlib/distro.sh +84 -0
- data/spec/shared/shlib/server.sh +423 -0
- data/spec/shared/shlib/set_env.sh +110 -0
- data/spec/support/expectations.rb +20 -18
- metadata +59 -6
@@ -126,4 +126,60 @@ describe 'has_many associations' do
|
|
126
126
|
end
|
127
127
|
end
|
128
128
|
end
|
129
|
+
|
130
|
+
context 'with deeply nested trees' do
|
131
|
+
let(:post) { HmmPost.create!(title: 'Post') }
|
132
|
+
let(:child) { post.comments.create!(title: 'Child') }
|
133
|
+
|
134
|
+
# creating grandchild will cascade to create the other documents
|
135
|
+
let!(:grandchild) { child.comments.create!(title: 'Grandchild') }
|
136
|
+
|
137
|
+
let(:updated_parent_title) { 'Post Updated' }
|
138
|
+
let(:updated_grandchild_title) { 'Grandchild Updated' }
|
139
|
+
|
140
|
+
context 'with nested attributes' do
|
141
|
+
let(:attributes) do
|
142
|
+
{
|
143
|
+
title: updated_parent_title,
|
144
|
+
comments_attributes: [
|
145
|
+
{
|
146
|
+
# no change for comment1
|
147
|
+
_id: child.id,
|
148
|
+
comments_attributes: [
|
149
|
+
{
|
150
|
+
_id: grandchild.id,
|
151
|
+
title: updated_grandchild_title,
|
152
|
+
num: updated_grandchild_num,
|
153
|
+
}
|
154
|
+
]
|
155
|
+
}
|
156
|
+
]
|
157
|
+
}
|
158
|
+
end
|
159
|
+
|
160
|
+
context 'when the grandchild is invalid' do
|
161
|
+
let(:updated_grandchild_num) { -1 } # invalid value
|
162
|
+
|
163
|
+
it 'will not save the parent' do
|
164
|
+
expect(post.update(attributes)).to be_falsey
|
165
|
+
expect(post.errors).not_to be_empty
|
166
|
+
expect(post.reload.title).not_to eq(updated_parent_title)
|
167
|
+
expect(grandchild.reload.title).not_to eq(updated_grandchild_title)
|
168
|
+
expect(grandchild.num).not_to eq(updated_grandchild_num)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
context 'when the grandchild is valid' do
|
173
|
+
let(:updated_grandchild_num) { 1 }
|
174
|
+
|
175
|
+
it 'will save the parent' do
|
176
|
+
expect(post.update(attributes)).to be_truthy
|
177
|
+
expect(post.errors).to be_empty
|
178
|
+
expect(post.reload.title).to eq(updated_parent_title)
|
179
|
+
expect(grandchild.reload.title).to eq(updated_grandchild_title)
|
180
|
+
expect(grandchild.num).to eq(updated_grandchild_num)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
129
185
|
end
|
@@ -224,7 +224,7 @@ describe 'has_one associations' do
|
|
224
224
|
end
|
225
225
|
|
226
226
|
context "when explicitly setting the foreign key" do
|
227
|
-
let(:comment2) { HomComment.new(
|
227
|
+
let(:comment2) { HomComment.new(container_id: post.id, container_type: post.class.name, content: "2") }
|
228
228
|
|
229
229
|
it "persists the new comment" do
|
230
230
|
post.comment = comment1
|
@@ -264,10 +264,62 @@ describe 'has_one associations' do
|
|
264
264
|
|
265
265
|
it "does not overwrite the original value" do
|
266
266
|
pending "MONGOID-3999"
|
267
|
-
p1 = comment.
|
267
|
+
p1 = comment.container
|
268
268
|
expect(p1.title).to eq("post 1")
|
269
|
-
comment.
|
269
|
+
comment.container = post2
|
270
270
|
expect(p1.title).to eq("post 1")
|
271
271
|
end
|
272
272
|
end
|
273
|
+
|
274
|
+
context 'with deeply nested trees' do
|
275
|
+
let(:post) { HomPost.create!(title: 'Post') }
|
276
|
+
let(:child) { post.create_comment(content: 'Child') }
|
277
|
+
|
278
|
+
# creating grandchild will cascade to create the other documents
|
279
|
+
let!(:grandchild) { child.create_comment(content: 'Grandchild') }
|
280
|
+
|
281
|
+
let(:updated_parent_title) { 'Post Updated' }
|
282
|
+
let(:updated_grandchild_content) { 'Grandchild Updated' }
|
283
|
+
|
284
|
+
context 'with nested attributes' do
|
285
|
+
let(:attributes) do
|
286
|
+
{
|
287
|
+
title: updated_parent_title,
|
288
|
+
comment_attributes: {
|
289
|
+
# no change for child
|
290
|
+
_id: child.id,
|
291
|
+
comment_attributes: {
|
292
|
+
_id: grandchild.id,
|
293
|
+
content: updated_grandchild_content,
|
294
|
+
num: updated_grandchild_num,
|
295
|
+
}
|
296
|
+
}
|
297
|
+
}
|
298
|
+
end
|
299
|
+
|
300
|
+
context 'when the grandchild is invalid' do
|
301
|
+
let(:updated_grandchild_num) { -1 } # invalid value
|
302
|
+
|
303
|
+
it 'will not save the parent' do
|
304
|
+
expect(post.update(attributes)).to be_falsey
|
305
|
+
expect(post.errors).not_to be_empty
|
306
|
+
expect(post.reload.title).not_to eq(updated_parent_title)
|
307
|
+
expect(grandchild.reload.content).not_to eq(updated_grandchild_content)
|
308
|
+
expect(grandchild.num).not_to eq(updated_grandchild_num)
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
context 'when the grandchild is valid' do
|
313
|
+
let(:updated_grandchild_num) { 1 }
|
314
|
+
|
315
|
+
it 'will save the parent' do
|
316
|
+
expect(post.update(attributes)).to be_truthy
|
317
|
+
expect(post.errors).to be_empty
|
318
|
+
expect(post.reload.title).to eq(updated_parent_title)
|
319
|
+
expect(grandchild.reload.content).to eq(updated_grandchild_content)
|
320
|
+
expect(grandchild.num).to eq(updated_grandchild_num)
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
324
|
+
end
|
273
325
|
end
|
@@ -96,3 +96,27 @@ class HmmAnimal
|
|
96
96
|
|
97
97
|
belongs_to :trainer, class_name: 'HmmTrainer', scope: -> { where(name: 'Dave') }
|
98
98
|
end
|
99
|
+
|
100
|
+
class HmmPost
|
101
|
+
include Mongoid::Document
|
102
|
+
|
103
|
+
field :title, type: String
|
104
|
+
|
105
|
+
has_many :comments, class_name: 'HmmComment', as: :container
|
106
|
+
|
107
|
+
accepts_nested_attributes_for :comments, allow_destroy: true
|
108
|
+
end
|
109
|
+
|
110
|
+
class HmmComment
|
111
|
+
include Mongoid::Document
|
112
|
+
|
113
|
+
field :title, type: String
|
114
|
+
field :num, type: Integer, default: 0
|
115
|
+
|
116
|
+
belongs_to :container, polymorphic: true
|
117
|
+
has_many :comments, class_name: 'HmmComment', as: :container
|
118
|
+
|
119
|
+
accepts_nested_attributes_for :comments, allow_destroy: true
|
120
|
+
|
121
|
+
validates :num, numericality: { greater_than_or_equal_to: 0 }
|
122
|
+
end
|
@@ -102,13 +102,21 @@ class HomPost
|
|
102
102
|
|
103
103
|
field :title, type: String
|
104
104
|
|
105
|
-
has_one :comment,
|
105
|
+
has_one :comment, as: :container, class_name: 'HomComment'
|
106
|
+
|
107
|
+
accepts_nested_attributes_for :comment, allow_destroy: true
|
106
108
|
end
|
107
109
|
|
108
110
|
class HomComment
|
109
111
|
include Mongoid::Document
|
110
112
|
|
111
113
|
field :content, type: String
|
114
|
+
field :num, type: Integer, default: 0
|
115
|
+
|
116
|
+
validates :num, numericality: { greater_than_or_equal_to: 0 }
|
117
|
+
|
118
|
+
belongs_to :container, polymorphic: true, optional: true
|
119
|
+
has_one :comment, as: :container, class_name: 'HomComment'
|
112
120
|
|
113
|
-
|
121
|
+
accepts_nested_attributes_for :comment, allow_destroy: true
|
114
122
|
end
|
@@ -115,66 +115,6 @@ 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
|
178
118
|
end
|
179
119
|
|
180
120
|
describe "#embedded_one?" do
|
@@ -716,7 +716,7 @@ describe Mongoid::Clients::Sessions do
|
|
716
716
|
require_transaction_support
|
717
717
|
|
718
718
|
context 'when no error raised' do
|
719
|
-
|
719
|
+
let!(:person) do
|
720
720
|
Mongoid.transaction do
|
721
721
|
Person.create!
|
722
722
|
end
|
@@ -727,6 +727,10 @@ describe Mongoid::Clients::Sessions do
|
|
727
727
|
expect(other_events.count { |e| e.command_name == 'commitTransaction'}).to be(1)
|
728
728
|
end
|
729
729
|
|
730
|
+
it 'returns the value from the block' do
|
731
|
+
expect(person).to be_a(Person)
|
732
|
+
end
|
733
|
+
|
730
734
|
it 'executes the commands inside the transaction' do
|
731
735
|
expect(Person.count).to be(1)
|
732
736
|
end
|
@@ -787,8 +791,12 @@ describe Mongoid::Clients::Sessions do
|
|
787
791
|
Mongoid::Clients.with_name(:default).database.collections.each(&:drop)
|
788
792
|
TransactionsSpecPerson.collection.create
|
789
793
|
TransactionsSpecPersonWithOnCreate.collection.create
|
794
|
+
TransactionsSpecPersonWithAfterCreateCommit.collection.create
|
790
795
|
TransactionsSpecPersonWithOnUpdate.collection.create
|
796
|
+
TransactionsSpecPersonWithAfterUpdateCommit.collection.create
|
797
|
+
TransactionsSpecPersonWithAfterSaveCommit.collection.create
|
791
798
|
TransactionsSpecPersonWithOnDestroy.collection.create
|
799
|
+
TransactionsSpecPersonWithAfterDestroyCommit.collection.create
|
792
800
|
TransactionSpecRaisesBeforeSave.collection.create
|
793
801
|
TransactionSpecRaisesAfterSave.collection.create
|
794
802
|
end
|
@@ -818,6 +826,18 @@ describe Mongoid::Clients::Sessions do
|
|
818
826
|
|
819
827
|
it_behaves_like 'commit callbacks are called'
|
820
828
|
end
|
829
|
+
|
830
|
+
context 'when callback is after_create_commit' do
|
831
|
+
let!(:subject) do
|
832
|
+
person = nil
|
833
|
+
TransactionsSpecPersonWithAfterCreateCommit.transaction do
|
834
|
+
person = TransactionsSpecPersonWithAfterCreateCommit.create!(name: 'James Bond')
|
835
|
+
end
|
836
|
+
person
|
837
|
+
end
|
838
|
+
|
839
|
+
it_behaves_like 'commit callbacks are called'
|
840
|
+
end
|
821
841
|
end
|
822
842
|
|
823
843
|
context 'save' do
|
@@ -886,6 +906,94 @@ describe Mongoid::Clients::Sessions do
|
|
886
906
|
it_behaves_like 'commit callbacks are called'
|
887
907
|
end
|
888
908
|
end
|
909
|
+
|
910
|
+
context 'with after_update_commit callback' do
|
911
|
+
let(:subject) do
|
912
|
+
TransactionsSpecPersonWithAfterUpdateCommit.create!(name: 'James Bond').tap do |subject|
|
913
|
+
subject.after_commit_counter.reset
|
914
|
+
subject.after_rollback_counter.reset
|
915
|
+
end
|
916
|
+
end
|
917
|
+
|
918
|
+
context 'when modified once' do
|
919
|
+
before do
|
920
|
+
subject.transaction do
|
921
|
+
subject.name = 'Austin Powers'
|
922
|
+
subject.save!
|
923
|
+
end
|
924
|
+
end
|
925
|
+
|
926
|
+
it_behaves_like 'commit callbacks are called'
|
927
|
+
end
|
928
|
+
|
929
|
+
context 'when modified multiple times' do
|
930
|
+
before do
|
931
|
+
subject.transaction do
|
932
|
+
subject.name = 'Austin Powers'
|
933
|
+
subject.save!
|
934
|
+
subject.name = 'Jason Bourne'
|
935
|
+
subject.save!
|
936
|
+
end
|
937
|
+
end
|
938
|
+
|
939
|
+
it_behaves_like 'commit callbacks are called'
|
940
|
+
end
|
941
|
+
end
|
942
|
+
|
943
|
+
context 'with after_save_commit callback' do
|
944
|
+
let(:subject) do
|
945
|
+
TransactionsSpecPersonWithAfterSaveCommit.create!(name: 'James Bond').tap do |subject|
|
946
|
+
subject.after_commit_counter.reset
|
947
|
+
subject.after_rollback_counter.reset
|
948
|
+
end
|
949
|
+
end
|
950
|
+
|
951
|
+
context 'when modified once' do
|
952
|
+
before do
|
953
|
+
subject.transaction do
|
954
|
+
subject.name = 'Austin Powers'
|
955
|
+
subject.save!
|
956
|
+
end
|
957
|
+
end
|
958
|
+
|
959
|
+
it_behaves_like 'commit callbacks are called'
|
960
|
+
end
|
961
|
+
|
962
|
+
context 'when created' do
|
963
|
+
before do
|
964
|
+
TransactionsSpecPersonWithAfterSaveCommit.transaction do
|
965
|
+
subject
|
966
|
+
end
|
967
|
+
end
|
968
|
+
|
969
|
+
it_behaves_like 'commit callbacks are called'
|
970
|
+
end
|
971
|
+
|
972
|
+
context 'when modified multiple times' do
|
973
|
+
before do
|
974
|
+
subject.transaction do
|
975
|
+
subject.name = 'Austin Powers'
|
976
|
+
subject.save!
|
977
|
+
subject.name = 'Jason Bourne'
|
978
|
+
subject.save!
|
979
|
+
end
|
980
|
+
end
|
981
|
+
|
982
|
+
it_behaves_like 'commit callbacks are called'
|
983
|
+
end
|
984
|
+
|
985
|
+
context 'when created and modified' do
|
986
|
+
before do
|
987
|
+
TransactionsSpecPersonWithAfterSaveCommit.transaction do
|
988
|
+
subject
|
989
|
+
subject.name = 'Jason Bourne'
|
990
|
+
subject.save!
|
991
|
+
end
|
992
|
+
end
|
993
|
+
|
994
|
+
it_behaves_like 'commit callbacks are called'
|
995
|
+
end
|
996
|
+
end
|
889
997
|
end
|
890
998
|
|
891
999
|
context 'update_attributes' do
|
@@ -919,6 +1027,34 @@ describe Mongoid::Clients::Sessions do
|
|
919
1027
|
|
920
1028
|
it_behaves_like 'commit callbacks are called'
|
921
1029
|
end
|
1030
|
+
|
1031
|
+
context 'when callback is after_update_commit' do
|
1032
|
+
let(:subject) do
|
1033
|
+
TransactionsSpecPersonWithAfterUpdateCommit.create!(name: 'Jason Bourne')
|
1034
|
+
end
|
1035
|
+
|
1036
|
+
before do
|
1037
|
+
TransactionsSpecPersonWithAfterUpdateCommit.transaction do
|
1038
|
+
subject.update_attributes!(name: 'Foma Kiniaev')
|
1039
|
+
end
|
1040
|
+
end
|
1041
|
+
|
1042
|
+
it_behaves_like 'commit callbacks are called'
|
1043
|
+
end
|
1044
|
+
|
1045
|
+
context 'when callback is after_save_commit' do
|
1046
|
+
let(:subject) do
|
1047
|
+
TransactionsSpecPersonWithAfterSaveCommit.create!(name: 'Jason Bourne')
|
1048
|
+
end
|
1049
|
+
|
1050
|
+
before do
|
1051
|
+
TransactionsSpecPersonWithAfterSaveCommit.transaction do
|
1052
|
+
subject.update_attributes!(name: 'Foma Kiniaev')
|
1053
|
+
end
|
1054
|
+
end
|
1055
|
+
|
1056
|
+
it_behaves_like 'commit callbacks are called'
|
1057
|
+
end
|
922
1058
|
end
|
923
1059
|
|
924
1060
|
context 'destroy' do
|
@@ -971,6 +1107,31 @@ describe Mongoid::Clients::Sessions do
|
|
971
1107
|
|
972
1108
|
it_behaves_like 'commit callbacks are called'
|
973
1109
|
end
|
1110
|
+
|
1111
|
+
context 'with after_destroy_commit' do
|
1112
|
+
let(:after_commit_counter) do
|
1113
|
+
TransactionsSpecCounter.new
|
1114
|
+
end
|
1115
|
+
|
1116
|
+
let(:after_rollback_counter) do
|
1117
|
+
TransactionsSpecCounter.new
|
1118
|
+
end
|
1119
|
+
|
1120
|
+
let(:subject) do
|
1121
|
+
TransactionsSpecPersonWithAfterDestroyCommit.create!(name: 'James Bond').tap do |p|
|
1122
|
+
p.after_commit_counter = after_commit_counter
|
1123
|
+
p.after_rollback_counter = after_rollback_counter
|
1124
|
+
end
|
1125
|
+
end
|
1126
|
+
|
1127
|
+
before do
|
1128
|
+
subject.transaction do
|
1129
|
+
subject.destroy
|
1130
|
+
end
|
1131
|
+
end
|
1132
|
+
|
1133
|
+
it_behaves_like 'commit callbacks are called'
|
1134
|
+
end
|
974
1135
|
end
|
975
1136
|
end
|
976
1137
|
|
@@ -33,6 +33,38 @@ module TransactionsSpecCountable
|
|
33
33
|
def after_rollback_counter=(new_counter)
|
34
34
|
@after_rollback_counter = new_counter
|
35
35
|
end
|
36
|
+
|
37
|
+
def after_save_commit_counter
|
38
|
+
@after_save_commit_counter ||= TransactionsSpecCounter.new
|
39
|
+
end
|
40
|
+
|
41
|
+
def after_save_commit_counter=(new_counter)
|
42
|
+
@after_save_commit_counter = new_counter
|
43
|
+
end
|
44
|
+
|
45
|
+
def after_create_commit_counter
|
46
|
+
@after_create_commit_counter ||= TransactionsSpecCounter.new
|
47
|
+
end
|
48
|
+
|
49
|
+
def after_create_commit_counter=(new_counter)
|
50
|
+
@after_create_commit_counter = new_counter
|
51
|
+
end
|
52
|
+
|
53
|
+
def after_update_commit_counter
|
54
|
+
@after_update_commit_counter ||= TransactionsSpecCounter.new
|
55
|
+
end
|
56
|
+
|
57
|
+
def after_update_commit_counter=(new_counter)
|
58
|
+
@after_update_commit_counter = new_counter
|
59
|
+
end
|
60
|
+
|
61
|
+
def after_destroy_commit_counter
|
62
|
+
@after_destroy_commit_counter ||= TransactionsSpecCounter.new
|
63
|
+
end
|
64
|
+
|
65
|
+
def after_destroy_commit_counter=(new_counter)
|
66
|
+
@after_destroy_commit_counter = new_counter
|
67
|
+
end
|
36
68
|
end
|
37
69
|
|
38
70
|
class TransactionsSpecPerson
|
@@ -65,6 +97,21 @@ class TransactionsSpecPersonWithOnCreate
|
|
65
97
|
end
|
66
98
|
end
|
67
99
|
|
100
|
+
class TransactionsSpecPersonWithAfterCreateCommit
|
101
|
+
include Mongoid::Document
|
102
|
+
include TransactionsSpecCountable
|
103
|
+
|
104
|
+
field :name, type: String
|
105
|
+
|
106
|
+
after_create_commit do
|
107
|
+
after_commit_counter.inc
|
108
|
+
end
|
109
|
+
|
110
|
+
after_rollback on: :create do
|
111
|
+
after_rollback_counter.inc
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
68
115
|
class TransactionsSpecPersonWithOnUpdate
|
69
116
|
include Mongoid::Document
|
70
117
|
include TransactionsSpecCountable
|
@@ -80,6 +127,36 @@ class TransactionsSpecPersonWithOnUpdate
|
|
80
127
|
end
|
81
128
|
end
|
82
129
|
|
130
|
+
class TransactionsSpecPersonWithAfterUpdateCommit
|
131
|
+
include Mongoid::Document
|
132
|
+
include TransactionsSpecCountable
|
133
|
+
|
134
|
+
field :name, type: String
|
135
|
+
|
136
|
+
after_update_commit do
|
137
|
+
after_commit_counter.inc
|
138
|
+
end
|
139
|
+
|
140
|
+
after_rollback on: :create do
|
141
|
+
after_rollback_counter.inc
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
class TransactionsSpecPersonWithAfterSaveCommit
|
146
|
+
include Mongoid::Document
|
147
|
+
include TransactionsSpecCountable
|
148
|
+
|
149
|
+
field :name, type: String
|
150
|
+
|
151
|
+
after_save_commit do
|
152
|
+
after_commit_counter.inc
|
153
|
+
end
|
154
|
+
|
155
|
+
after_rollback on: :create do
|
156
|
+
after_rollback_counter.inc
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
83
160
|
class TransactionsSpecPersonWithOnDestroy
|
84
161
|
include Mongoid::Document
|
85
162
|
include TransactionsSpecCountable
|
@@ -94,6 +171,22 @@ class TransactionsSpecPersonWithOnDestroy
|
|
94
171
|
after_rollback_counter.inc
|
95
172
|
end
|
96
173
|
end
|
174
|
+
|
175
|
+
class TransactionsSpecPersonWithAfterDestroyCommit
|
176
|
+
include Mongoid::Document
|
177
|
+
include TransactionsSpecCountable
|
178
|
+
|
179
|
+
field :name, type: String
|
180
|
+
|
181
|
+
after_destroy_commit do
|
182
|
+
after_commit_counter.inc
|
183
|
+
end
|
184
|
+
|
185
|
+
after_rollback on: :create do
|
186
|
+
after_rollback_counter.inc
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
97
190
|
class TransactionSpecRaisesBeforeSave
|
98
191
|
include Mongoid::Document
|
99
192
|
include TransactionsSpecCountable
|
@@ -244,6 +244,39 @@ describe Mongoid::Contextual::Aggregable::Mongo do
|
|
244
244
|
end
|
245
245
|
end
|
246
246
|
end
|
247
|
+
|
248
|
+
context 'regarding hints' do
|
249
|
+
let(:client) { Person.collection.client }
|
250
|
+
let(:subscriber) { Mrss::EventSubscriber.new }
|
251
|
+
|
252
|
+
before do
|
253
|
+
client.subscribe(Mongo::Monitoring::COMMAND, subscriber)
|
254
|
+
maybe_hint.aggregates(:age)
|
255
|
+
end
|
256
|
+
|
257
|
+
after do
|
258
|
+
client.unsubscribe(Mongo::Monitoring::COMMAND, subscriber)
|
259
|
+
end
|
260
|
+
|
261
|
+
let(:event) { subscriber.single_command_started_event('aggregate') }
|
262
|
+
let(:command) { event.command }
|
263
|
+
|
264
|
+
context 'when no hint is provided' do
|
265
|
+
let(:maybe_hint) { Person }
|
266
|
+
|
267
|
+
it 'does not include the hint in the command' do
|
268
|
+
expect(command['hint']).to be_nil
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
context 'when a hint is provided' do
|
273
|
+
let(:maybe_hint) { Person.hint(age: 1) }
|
274
|
+
|
275
|
+
it 'includes the hint with the command' do
|
276
|
+
expect(command['hint']).to eq({ 'age' => 1 })
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
247
280
|
end
|
248
281
|
|
249
282
|
describe "#avg" do
|
@@ -3282,6 +3282,12 @@ describe Mongoid::Contextual::Mongo do
|
|
3282
3282
|
it "limits the results" do
|
3283
3283
|
expect(context.skip(1).entries).to eq([ new_order ])
|
3284
3284
|
end
|
3285
|
+
|
3286
|
+
context "with #last" do
|
3287
|
+
it "returns the nth from last element" do
|
3288
|
+
expect(context.skip(1).last).to eq(depeche_mode)
|
3289
|
+
end
|
3290
|
+
end
|
3285
3291
|
end
|
3286
3292
|
|
3287
3293
|
describe "#sort" do
|
@@ -134,6 +134,16 @@ describe Mongoid::Reloadable do
|
|
134
134
|
|
135
135
|
agent.title.should == '007'
|
136
136
|
end
|
137
|
+
|
138
|
+
it 'sets new_record to false' do
|
139
|
+
expect(agent.new_record?).to be true
|
140
|
+
|
141
|
+
lambda do
|
142
|
+
agent.reload
|
143
|
+
end.should_not raise_error
|
144
|
+
|
145
|
+
expect(agent.new_record?).to be false
|
146
|
+
end
|
137
147
|
end
|
138
148
|
end
|
139
149
|
|
@@ -596,6 +606,20 @@ describe Mongoid::Reloadable do
|
|
596
606
|
band.id.should_not == original_id
|
597
607
|
end
|
598
608
|
end
|
609
|
+
|
610
|
+
context 'when there is no document matching our id' do
|
611
|
+
let(:agent) { Agent.new(id: BSON::ObjectId.new) }
|
612
|
+
|
613
|
+
it 'does not set new_record to false' do
|
614
|
+
expect(agent.new_record?).to be true
|
615
|
+
|
616
|
+
lambda do
|
617
|
+
agent.reload
|
618
|
+
end.should_not raise_error
|
619
|
+
|
620
|
+
expect(agent.new_record?).to be true
|
621
|
+
end
|
622
|
+
end
|
599
623
|
end
|
600
624
|
|
601
625
|
context 'when document has referenced associations' do
|
@@ -29,5 +29,21 @@ describe ActiveModel::Validations::NumericalityValidator do
|
|
29
29
|
expect(model).to_not be_valid
|
30
30
|
end
|
31
31
|
end
|
32
|
+
|
33
|
+
context 'when the value is numeric' do
|
34
|
+
let(:model) { TestModel.new(amount: '15.0') }
|
35
|
+
|
36
|
+
it 'returns true' do
|
37
|
+
expect(model).to be_valid
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'when the value is a BSON::Decimal128' do
|
42
|
+
let(:model) { TestModel.new(amount: BSON::Decimal128.new('15.0')) }
|
43
|
+
|
44
|
+
it 'returns true' do
|
45
|
+
expect(model).to be_valid
|
46
|
+
end
|
47
|
+
end
|
32
48
|
end
|
33
49
|
end
|