mongoid 4.0.2 → 5.0.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 (185) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -1
  3. data/README.md +11 -19
  4. data/lib/config/locales/en.yml +33 -30
  5. data/lib/mongoid/atomic.rb +2 -4
  6. data/lib/mongoid/attributes/processing.rb +4 -1
  7. data/lib/mongoid/attributes/readonly.rb +2 -2
  8. data/lib/mongoid/attributes.rb +7 -7
  9. data/lib/mongoid/changeable.rb +4 -6
  10. data/lib/mongoid/clients/factory.rb +78 -0
  11. data/lib/mongoid/{sessions → clients}/options.rb +30 -19
  12. data/lib/mongoid/{sessions → clients}/storage_options.rb +27 -13
  13. data/lib/mongoid/{sessions → clients}/thread_options.rb +6 -3
  14. data/lib/mongoid/{sessions → clients}/validators/storage.rb +5 -2
  15. data/lib/mongoid/clients/validators.rb +2 -0
  16. data/lib/mongoid/clients.rb +141 -0
  17. data/lib/mongoid/composable.rb +3 -3
  18. data/lib/mongoid/config/environment.rb +1 -1
  19. data/lib/mongoid/config/options.rb +1 -1
  20. data/lib/mongoid/config/validators/{session.rb → client.rb} +31 -28
  21. data/lib/mongoid/config/validators/option.rb +1 -1
  22. data/lib/mongoid/config/validators.rb +1 -1
  23. data/lib/mongoid/config.rb +39 -41
  24. data/lib/mongoid/contextual/aggregable/mongo.rb +1 -1
  25. data/lib/mongoid/contextual/atomic.rb +11 -11
  26. data/lib/mongoid/contextual/command.rb +9 -6
  27. data/lib/mongoid/contextual/geo_near.rb +17 -1
  28. data/lib/mongoid/contextual/map_reduce.rb +12 -11
  29. data/lib/mongoid/contextual/memory.rb +2 -5
  30. data/lib/mongoid/contextual/mongo.rb +92 -82
  31. data/lib/mongoid/contextual/none.rb +13 -0
  32. data/lib/mongoid/copyable.rb +6 -1
  33. data/lib/mongoid/criteria.rb +37 -4
  34. data/lib/mongoid/document.rb +3 -4
  35. data/lib/mongoid/errors/{mixed_session_configuration.rb → mixed_client_configuration.rb} +5 -5
  36. data/lib/mongoid/errors/mongoid_error.rb +15 -9
  37. data/lib/mongoid/errors/no_client_config.rb +22 -0
  38. data/lib/mongoid/errors/{no_session_database.rb → no_client_database.rb} +4 -4
  39. data/lib/mongoid/errors/{no_session_hosts.rb → no_client_hosts.rb} +4 -4
  40. data/lib/mongoid/errors/{no_sessions_config.rb → no_clients_config.rb} +4 -4
  41. data/lib/mongoid/errors/no_default_client.rb +23 -0
  42. data/lib/mongoid/errors.rb +6 -6
  43. data/lib/mongoid/extensions/hash.rb +5 -1
  44. data/lib/mongoid/extensions/object.rb +3 -2
  45. data/lib/mongoid/extensions/set.rb +5 -5
  46. data/lib/mongoid/factory.rb +4 -2
  47. data/lib/mongoid/fields.rb +7 -2
  48. data/lib/mongoid/findable.rb +4 -1
  49. data/lib/mongoid/indexable.rb +15 -9
  50. data/lib/mongoid/persistable/creatable.rb +2 -2
  51. data/lib/mongoid/persistable/deletable.rb +3 -3
  52. data/lib/mongoid/persistable/incrementable.rb +1 -1
  53. data/lib/mongoid/persistable/logical.rb +1 -1
  54. data/lib/mongoid/persistable/poppable.rb +1 -1
  55. data/lib/mongoid/persistable/pullable.rb +2 -2
  56. data/lib/mongoid/persistable/pushable.rb +2 -2
  57. data/lib/mongoid/persistable/renamable.rb +1 -1
  58. data/lib/mongoid/persistable/settable.rb +1 -1
  59. data/lib/mongoid/persistable/unsettable.rb +1 -1
  60. data/lib/mongoid/persistable/updatable.rb +2 -2
  61. data/lib/mongoid/persistable/upsertable.rb +1 -1
  62. data/lib/mongoid/persistable.rb +1 -2
  63. data/lib/mongoid/query_cache.rb +98 -104
  64. data/lib/mongoid/railtie.rb +4 -25
  65. data/lib/mongoid/railties/database.rake +1 -1
  66. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +3 -2
  67. data/lib/mongoid/relations/builders.rb +3 -1
  68. data/lib/mongoid/relations/counter_cache.rb +1 -1
  69. data/lib/mongoid/relations/embedded/batchable.rb +3 -10
  70. data/lib/mongoid/relations/embedded/many.rb +4 -2
  71. data/lib/mongoid/relations/embedded/one.rb +1 -0
  72. data/lib/mongoid/relations/many.rb +1 -0
  73. data/lib/mongoid/relations/metadata.rb +14 -0
  74. data/lib/mongoid/relations/proxy.rb +6 -6
  75. data/lib/mongoid/relations/referenced/many.rb +2 -1
  76. data/lib/mongoid/relations/targets/enumerable.rb +11 -11
  77. data/lib/mongoid/relations/touchable.rb +1 -1
  78. data/lib/mongoid/reloadable.rb +2 -2
  79. data/lib/mongoid/scopable.rb +6 -17
  80. data/lib/mongoid/selectable.rb +1 -36
  81. data/lib/mongoid/serializable.rb +2 -2
  82. data/lib/mongoid/stateful.rb +0 -1
  83. data/lib/mongoid/tasks/database.rake +2 -2
  84. data/lib/mongoid/tasks/database.rb +24 -17
  85. data/lib/mongoid/threaded/lifecycle.rb +21 -16
  86. data/lib/mongoid/threaded.rb +54 -33
  87. data/lib/mongoid/traversable.rb +17 -1
  88. data/lib/mongoid/validatable/queryable.rb +1 -1
  89. data/lib/mongoid/validatable/uniqueness.rb +3 -20
  90. data/lib/mongoid/validatable.rb +1 -1
  91. data/lib/mongoid/version.rb +1 -1
  92. data/lib/mongoid.rb +28 -21
  93. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +91 -57
  94. data/lib/rails/mongoid.rb +2 -2
  95. data/spec/app/models/audio.rb +1 -1
  96. data/spec/app/models/band.rb +1 -0
  97. data/spec/app/models/code.rb +6 -0
  98. data/spec/app/models/company.rb +5 -0
  99. data/spec/app/models/label.rb +7 -0
  100. data/spec/app/models/pub.rb +6 -0
  101. data/spec/app/models/staff.rb +7 -0
  102. data/spec/app/models/store_as_dup_test1.rb +5 -0
  103. data/spec/app/models/store_as_dup_test2.rb +5 -0
  104. data/spec/config/mongoid.yml +7 -25
  105. data/spec/mongoid/atomic/paths_spec.rb +3 -11
  106. data/spec/mongoid/attributes/nested_spec.rb +16 -16
  107. data/spec/mongoid/attributes/readonly_spec.rb +80 -18
  108. data/spec/mongoid/attributes_spec.rb +3 -3
  109. data/spec/mongoid/changeable_spec.rb +156 -0
  110. data/spec/mongoid/clients/factory_spec.rb +284 -0
  111. data/spec/mongoid/{sessions → clients}/options_spec.rb +4 -6
  112. data/spec/mongoid/clients_spec.rb +754 -0
  113. data/spec/mongoid/config/environment_spec.rb +14 -11
  114. data/spec/mongoid/config_spec.rb +33 -48
  115. data/spec/mongoid/contextual/atomic_spec.rb +1 -17
  116. data/spec/mongoid/contextual/geo_near_spec.rb +35 -0
  117. data/spec/mongoid/contextual/mongo_spec.rb +26 -83
  118. data/spec/mongoid/contextual/none_spec.rb +15 -0
  119. data/spec/mongoid/copyable_spec.rb +35 -1
  120. data/spec/mongoid/criteria/findable_spec.rb +197 -0
  121. data/spec/mongoid/criteria/modifiable_spec.rb +7 -29
  122. data/spec/mongoid/criteria_spec.rb +74 -91
  123. data/spec/mongoid/document_spec.rb +1 -1
  124. data/spec/mongoid/errors/{mixed_session_configuration_spec.rb → mixed_client_configuration_spec.rb} +1 -1
  125. data/spec/mongoid/errors/mongoid_error_spec.rb +19 -3
  126. data/spec/mongoid/errors/{no_session_config_spec.rb → no_client_config_spec.rb} +4 -4
  127. data/spec/mongoid/errors/{no_session_database_spec.rb → no_client_database_spec.rb} +4 -4
  128. data/spec/mongoid/errors/{no_session_hosts_spec.rb → no_client_hosts_spec.rb} +3 -3
  129. data/spec/mongoid/errors/{no_sessions_config_spec.rb → no_clients_config_spec.rb} +2 -2
  130. data/spec/mongoid/fields/localized_spec.rb +1 -0
  131. data/spec/mongoid/fields_spec.rb +1 -0
  132. data/spec/mongoid/findable_spec.rb +2 -23
  133. data/spec/mongoid/indexable_spec.rb +12 -8
  134. data/spec/mongoid/interceptable_spec.rb +15 -0
  135. data/spec/mongoid/persistable/settable_spec.rb +16 -0
  136. data/spec/mongoid/persistable/updatable_spec.rb +3 -2
  137. data/spec/mongoid/persistable_spec.rb +4 -4
  138. data/spec/mongoid/query_cache_spec.rb +13 -8
  139. data/spec/mongoid/relations/auto_save_spec.rb +1 -1
  140. data/spec/mongoid/relations/counter_cache_spec.rb +34 -0
  141. data/spec/mongoid/relations/eager/belongs_to_spec.rb +9 -0
  142. data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +3 -3
  143. data/spec/mongoid/relations/embedded/many_spec.rb +123 -1
  144. data/spec/mongoid/relations/embedded/one_spec.rb +3 -3
  145. data/spec/mongoid/relations/proxy_spec.rb +28 -0
  146. data/spec/mongoid/relations/referenced/in_spec.rb +1 -1
  147. data/spec/mongoid/relations/referenced/many_spec.rb +47 -23
  148. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +1 -1
  149. data/spec/mongoid/relations/referenced/one_spec.rb +1 -1
  150. data/spec/mongoid/relations/targets/enumerable_spec.rb +9 -2
  151. data/spec/mongoid/reloadable_spec.rb +6 -6
  152. data/spec/mongoid/scopable_spec.rb +41 -28
  153. data/spec/mongoid/selectable_spec.rb +6 -16
  154. data/spec/mongoid/tasks/database_rake_spec.rb +13 -13
  155. data/spec/mongoid/tasks/database_spec.rb +2 -2
  156. data/spec/mongoid/threaded_spec.rb +0 -7
  157. data/spec/mongoid/traversable_spec.rb +2 -2
  158. data/spec/mongoid/validatable/uniqueness_spec.rb +30 -1
  159. data/spec/mongoid_spec.rb +13 -15
  160. data/spec/rails/mongoid_spec.rb +13 -4
  161. data/spec/spec_helper.rb +44 -27
  162. data/spec/support/authorization.rb +12 -0
  163. data/spec/support/expectations.rb +14 -0
  164. metadata +50 -57
  165. data/lib/mongoid/contextual/find_and_modify.rb +0 -69
  166. data/lib/mongoid/contextual/text_search.rb +0 -178
  167. data/lib/mongoid/criteria/#findable.rb# +0 -141
  168. data/lib/mongoid/errors/no_default_session.rb +0 -23
  169. data/lib/mongoid/errors/no_session_config.rb +0 -22
  170. data/lib/mongoid/log_subscriber.rb +0 -55
  171. data/lib/mongoid/positional.rb +0 -71
  172. data/lib/mongoid/sessions/factory.rb +0 -131
  173. data/lib/mongoid/sessions/mongo_uri.rb +0 -93
  174. data/lib/mongoid/sessions/validators.rb +0 -2
  175. data/lib/mongoid/sessions.rb +0 -125
  176. data/lib/mongoid/support/query_counter.rb +0 -23
  177. data/spec/helpers.rb +0 -18
  178. data/spec/mongoid/#atomic_spec.rb# +0 -365
  179. data/spec/mongoid/contextual/find_and_modify_spec.rb +0 -220
  180. data/spec/mongoid/contextual/text_search_spec.rb +0 -209
  181. data/spec/mongoid/log_subscriber_spec.rb +0 -75
  182. data/spec/mongoid/positional_spec.rb +0 -222
  183. data/spec/mongoid/sessions/factory_spec.rb +0 -333
  184. data/spec/mongoid/sessions/mongo_uri_spec.rb +0 -103
  185. data/spec/mongoid/sessions_spec.rb +0 -1252
@@ -1,2 +0,0 @@
1
- # encoding: utf-8
2
- require "mongoid/sessions/validators/storage"
@@ -1,125 +0,0 @@
1
- # encoding: utf-8
2
- require "mongoid/sessions/factory"
3
- require "mongoid/sessions/validators"
4
- require "mongoid/sessions/storage_options"
5
- require "mongoid/sessions/thread_options"
6
- require "mongoid/sessions/options"
7
-
8
- module Mongoid
9
- module Sessions
10
- extend ActiveSupport::Concern
11
- include StorageOptions
12
- include ThreadOptions
13
- include Options
14
-
15
- class << self
16
- # Clear all sessions from the current thread.
17
- #
18
- # @example Clear all sessions.
19
- # Mongoid::Sessions.clear
20
- #
21
- # @return [ Array ] The empty sessions.
22
- #
23
- # @since 3.0.0
24
- def clear
25
- Threaded.sessions.clear
26
- end
27
-
28
- # Get the default session.
29
- #
30
- # @example Get the default session.
31
- # Mongoid::Sessions.default
32
- #
33
- # @return [ Moped::Session ] The default session.
34
- #
35
- # @since 3.0.0
36
- def default
37
- Threaded.sessions[:default] ||= Sessions::Factory.default
38
- end
39
-
40
- # Disconnect all active sessions.
41
- #
42
- # @example Disconnect all active sessions.
43
- # Mongoid::Sessions.disconnect
44
- #
45
- # @return [ true ] True.
46
- #
47
- # @since 3.1.0
48
- def disconnect
49
- Threaded.sessions.values.each do |session|
50
- session.disconnect
51
- end
52
- end
53
-
54
- # Get a session with the provided name.
55
- #
56
- # @example Get a session with the name.
57
- # Mongoid::Sessions.with_name(:replica)
58
- #
59
- # @param [ Symbol ] name The name of the session.
60
- #
61
- # @return [ Moped::Session ] The named session.
62
- #
63
- # @since 3.0.0
64
- def with_name(name)
65
- Threaded.sessions[name.to_sym] ||= Sessions::Factory.create(name)
66
- end
67
- end
68
-
69
- # Get the collection for this model from the session. Will check for an
70
- # overridden collection name from the store_in macro or the collection
71
- # with a pluralized model name.
72
- #
73
- # @example Get the model's collection.
74
- # Model.collection
75
- #
76
- # @return [ Moped::Collection ] The collection.
77
- #
78
- # @since 3.0.0
79
- def collection
80
- mongo_session[collection_name]
81
- end
82
-
83
- def mongo_session
84
- super || self.class.mongo_session
85
- end
86
-
87
- def collection_name
88
- super || self.class.collection_name
89
- end
90
-
91
- module ClassMethods
92
-
93
- # Get the session for this model. This is determined in the following order:
94
- #
95
- # 1. Any custom configuration provided by the 'store_in' macro.
96
- # 2. The 'default' session as provided in the mongoid.yml
97
- #
98
- # @example Get the session.
99
- # Model.mongo_session
100
- #
101
- # @return [ Moped::Session ] The default moped session.
102
- #
103
- # @since 3.0.0
104
- def mongo_session
105
- session = Sessions.with_name(session_name)
106
- session.use(database_name)
107
- self.persistence_options ? session.with(self.persistence_options) : session
108
- end
109
-
110
- # Get the collection for this model from the session. Will check for an
111
- # overridden collection name from the store_in macro or the collection
112
- # with a pluralized model name.
113
- #
114
- # @example Get the model's collection.
115
- # Model.collection
116
- #
117
- # @return [ Moped::Collection ] The collection.
118
- #
119
- # @since 3.0.0
120
- def collection
121
- mongo_session[collection_name]
122
- end
123
- end
124
- end
125
- end
@@ -1,23 +0,0 @@
1
- module Mongoid
2
-
3
- class QueryCounter
4
- attr_reader :events
5
-
6
- def initialize
7
- @events = []
8
- end
9
-
10
- def instrument
11
- subscriber = ActiveSupport::Notifications.subscribe('query.moped') do |*args|
12
- @events << ActiveSupport::Notifications::Event.new(*args)
13
- end
14
- yield
15
- ensure
16
- ActiveSupport::Notifications.unsubscribe(subscriber)
17
- end
18
-
19
- def inspect
20
- @events.map { |e| e.payload[:ops].map(&:log_inspect) }.join("\n")
21
- end
22
- end
23
- end
data/spec/helpers.rb DELETED
@@ -1,18 +0,0 @@
1
- require 'mongoid/support/query_counter'
2
-
3
- module Mongoid
4
- module SpecHelpers
5
- def expect_query(number, &block)
6
- query_counter = Mongoid::QueryCounter.new
7
- query_counter.instrument(&block)
8
- expect(query_counter.events.size).to(eq(number), %[
9
- Expected to receive #{number} queries, it received #{query_counter.events.size}
10
- #{query_counter.inspect}
11
- ])
12
- end
13
-
14
- def expect_no_queries(&block)
15
- expect_query(0, &block)
16
- end
17
- end
18
- end
@@ -1,365 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Mongoid::Atomic do
4
-
5
- describe "#add_atomic_pull" do
6
-
7
- let!(:person) do
8
- Person.create
9
- end
10
-
11
- let(:address) do
12
- person.addresses.create
13
- end
14
-
15
- let(:location) do
16
- address.locations.create
17
- end
18
-
19
- before do
20
- person.add_atomic_pull(address)
21
- end
22
-
23
- it "adds the document to the delayed atomic pulls" do
24
- expect(person.delayed_atomic_pulls["addresses"]).to eq([ address ])
25
- end
26
-
27
- it "flags the document for destruction" do
28
- expect(address).to be_flagged_for_destroy
29
- end
30
- end
31
-
32
- describe "#add_atomic_unset" do
33
-
34
- let!(:person) do
35
- Person.new
36
- end
37
-
38
- let(:name) do
39
- person.build_name
40
- end
41
-
42
- before do
43
- person.add_atomic_unset(name)
44
- end
45
-
46
- it "adds the document to the delayed atomic unsets" do
47
- expect(person.delayed_atomic_unsets["name"]).to eq([ name ])
48
- end
49
-
50
- it "flags the document for destruction" do
51
- expect(name).to be_flagged_for_destroy
52
- end
53
- end
54
-
55
- describe "#atomic_updates" do
56
-
57
- context "when the document is persisted" do
58
-
59
- let(:person) do
60
- Person.create
61
- end
62
-
63
- context "when the document is modified" do
64
-
65
- before do
66
- person.title = "Sir"
67
- end
68
-
69
- it "returns the atomic updates" do
70
- expect(person.atomic_updates).to eq({ "$set" => { "title" => "Sir" }})
71
- end
72
-
73
- context "when an embeds many child is added" do
74
-
75
- let!(:address) do
76
- person.addresses.build(street: "Oxford St")
77
- end
78
-
79
- it "returns a $set and $pushAll for modifications" do
80
- expect(person.atomic_updates).to eq(
81
- {
82
- "$set" => { "title" => "Sir" },
83
- "$pushAll" => { "addresses" => [
84
- { "_id" => "oxford-st", "street" => "Oxford St" }
85
- ]}
86
- }
87
- )
88
- end
89
- end
90
-
91
- context "when an embeds one child is added" do
92
-
93
- let!(:name) do
94
- person.build_name(first_name: "Lionel")
95
- end
96
-
97
- it "returns a $set for modifications" do
98
- expect(person.atomic_updates).to eq(
99
- {
100
- "$set" => {
101
- "title" => "Sir",
102
- "name" => { "_id" => "Lionel-", "first_name" => "Lionel" }
103
- }
104
- }
105
- )
106
- end
107
- end
108
-
109
- context "when an existing embeds many gets modified" do
110
-
111
- let!(:address) do
112
- person.addresses.create(street: "Oxford St")
113
- end
114
-
115
- before do
116
- address.street = "Bond St"
117
- end
118
-
119
- context "when asking for the updates from the root" do
120
-
121
- it "returns the $set with correct position and modifications" do
122
- expect(person.atomic_updates).to eq(
123
- { "$set" => { "title" => "Sir", "addresses.0.street" => "Bond St" }}
124
- )
125
- end
126
- end
127
-
128
- context "when asking for the updates from the child" do
129
-
130
- it "returns the $set with correct position and modifications" do
131
- expect(address.atomic_updates).to eq(
132
- { "$set" => { "addresses.0.street" => "Bond St" }}
133
- )
134
- end
135
- end
136
-
137
- context "when an existing 2nd level embedded child gets modified" do
138
-
139
- let!(:location) do
140
- address.locations.create(name: "Home")
141
- end
142
-
143
- before do
144
- location.name = "Work"
145
- end
146
-
147
- context "when asking for the updates from the root" do
148
-
149
- it "returns the $set with correct positions and modifications" do
150
- expect(person.atomic_updates).to eq(
151
- { "$set" => {
152
- "title" => "Sir",
153
- "addresses.0.street" => "Bond St",
154
- "addresses.0.locations.0.name" => "Work" }
155
- }
156
- )
157
- end
158
- end
159
-
160
- context "when asking for the updates from the 1st level child" do
161
-
162
- it "returns the $set with correct positions and modifications" do
163
- expect(address.atomic_updates).to eq(
164
- { "$set" => {
165
- "addresses.0.street" => "Bond St",
166
- "addresses.0.locations.0.name" => "Work" }
167
- }
168
- )
169
- end
170
- end
171
-
172
- context "when asking for the updates from the 2nd level child" do
173
-
174
- it "returns the $set with correct positions and modifications" do
175
- expect(location.atomic_updates).to eq(
176
- { "$set" => {
177
- "addresses.0.locations.0.name" => "Work" }
178
- }
179
- )
180
- end
181
- end
182
- end
183
-
184
- context "when a 2nd level embedded child gets added" do
185
-
186
- let!(:location) do
187
- address.locations.build(name: "Home")
188
- end
189
-
190
- context "when asking for the updates from the root" do
191
-
192
- it "returns the $set with correct positions and modifications" do
193
- expect(person.atomic_updates).to eq(
194
- {
195
- "$set" => {
196
- "title" => "Sir",
197
- "addresses.0.street" => "Bond St"
198
- },
199
- conflicts: {
200
- "$pushAll" => {
201
- "addresses.0.locations" => [{ "_id" => location.id, "name" => "Home" }]
202
- }
203
- }
204
- }
205
- )
206
- end
207
- end
208
-
209
- context "when asking for the updates from the 1st level child" do
210
-
211
- it "returns the $set with correct positions and modifications" do
212
- expect(address.atomic_updates).to eq(
213
- {
214
- "$set" => {
215
- "addresses.0.street" => "Bond St"
216
- },
217
- conflicts: {
218
- "$pushAll" => {
219
- "addresses.0.locations" => [{ "_id" => location.id, "name" => "Home" }]
220
- }
221
- }
222
- }
223
- )
224
- end
225
- end
226
- end
227
-
228
- context "when an embedded child gets unset" do
229
-
230
- before do
231
- person.attributes = { addresses: nil }
232
- end
233
-
234
- let(:updates) do
235
- person.atomic_updates
236
- end
237
-
238
- it "returns the $set for the first level and $unset for other." do
239
- expect(updates).to eq({
240
- "$unset" => { "addresses" => true },
241
- "$set" => { "title" => "Sir" }
242
- })
243
- end
244
- end
245
-
246
- context "when adding a new second level child" do
247
-
248
- let!(:new_address) do
249
- person.addresses.build(street: "Another")
250
- end
251
-
252
- let!(:location) do
253
- new_address.locations.build(name: "Home")
254
- end
255
-
256
- context "when asking for the updates from the root document" do
257
-
258
- it "returns the $set for 1st level and other for the 2nd level" do
259
- expect(person.atomic_updates).to eq(
260
- {
261
- "$set" => {
262
- "title" => "Sir",
263
- "addresses.0.street" => "Bond St"
264
- },
265
- conflicts: {
266
- "$pushAll" => {
267
- "addresses" => [{
268
- "_id" => new_address.id,
269
- "street" => "Another",
270
- "locations" => [
271
- "_id" => location.id,
272
- "name" => "Home"
273
- ]
274
- }]
275
- }
276
- }
277
- }
278
- )
279
- end
280
- end
281
-
282
- context "when asking for the updates from the 1st level document" do
283
-
284
- it "returns the $set for 1st level and other for the 2nd level" do
285
- expect(address.atomic_updates).to eq(
286
- { "$set" => { "addresses.0.street" => "Bond St" }}
287
- )
288
- end
289
- end
290
- end
291
-
292
- context "when adding a new child beetween two existing and updating one of them" do
293
-
294
- let!(:new_address) do
295
- person.addresses.build(street: "Ipanema")
296
- end
297
-
298
- let!(:location) do
299
- new_address.locations.build(name: "Home")
300
- end
301
-
302
- before do
303
- person.addresses[0] = new_address
304
- person.addresses[1] = address
305
- end
306
-
307
- it "returns the $set for 1st and 2nd level and other for the 3nd level" do
308
- expect(person.atomic_updates).to eq(
309
- {
310
- "$set" => {
311
- "title" => "Sir"
312
- },
313
- "$pushAll" => {
314
- "addresses" => [{
315
- "_id" => new_address.id,
316
- "street" => "Ipanema",
317
- "locations" => [
318
- "_id" => location.id,
319
- "name" => "Home"
320
- ]
321
- }]
322
- },
323
- conflicts: {
324
- "$set" => { "addresses.0.street"=>"Bond St" }
325
- }
326
- }
327
- )
328
- end
329
- end
330
- end
331
-
332
- context "when adding new embedded docs at multiple levels" do
333
-
334
- let!(:address) do
335
- person.addresses.build(street: "Another")
336
- end
337
-
338
- let!(:location) do
339
- address.locations.build(name: "Home")
340
- end
341
-
342
- it "returns the proper $sets and $pushAlls for all levels" do
343
- expect(person.atomic_updates).to eq(
344
- {
345
- "$set" => {
346
- "title" => "Sir",
347
- },
348
- "$pushAll" => {
349
- "addresses" => [{
350
- "_id" => address.id,
351
- "street" => "Another",
352
- "locations" => [
353
- "_id" => location.id,
354
- "name" => "Home"
355
- ]
356
- }]
357
- }
358
- }
359
- )
360
- end
361
- end
362
- end
363
- end
364
- end
365
- end