mongoid 5.4.1 → 6.1.1

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 (260) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +3 -3
  3. data/lib/config/locales/en.yml +19 -0
  4. data/lib/mongoid.rb +4 -4
  5. data/lib/mongoid/atomic.rb +2 -2
  6. data/lib/mongoid/atomic/modifiers.rb +8 -12
  7. data/lib/mongoid/attributes.rb +22 -21
  8. data/lib/mongoid/attributes/readonly.rb +22 -0
  9. data/lib/mongoid/cacheable.rb +36 -0
  10. data/lib/mongoid/changeable.rb +36 -0
  11. data/lib/mongoid/clients.rb +8 -63
  12. data/lib/mongoid/clients/options.rb +55 -250
  13. data/lib/mongoid/clients/storage_options.rb +1 -69
  14. data/lib/mongoid/composable.rb +29 -3
  15. data/lib/mongoid/config.rb +1 -0
  16. data/lib/mongoid/contextual/atomic.rb +5 -8
  17. data/lib/mongoid/contextual/map_reduce.rb +0 -4
  18. data/lib/mongoid/contextual/memory.rb +2 -2
  19. data/lib/mongoid/contextual/mongo.rb +40 -22
  20. data/lib/mongoid/contextual/none.rb +12 -0
  21. data/lib/mongoid/copyable.rb +13 -6
  22. data/lib/mongoid/criteria.rb +5 -2
  23. data/lib/mongoid/criteria/marshalable.rb +2 -2
  24. data/lib/mongoid/criteria/modifiable.rb +17 -1
  25. data/lib/mongoid/criteria/options.rb +25 -0
  26. data/lib/mongoid/criteria/queryable.rb +87 -0
  27. data/lib/mongoid/criteria/queryable/aggregable.rb +120 -0
  28. data/lib/mongoid/criteria/queryable/extensions.rb +28 -0
  29. data/lib/mongoid/criteria/queryable/extensions/array.rb +185 -0
  30. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +37 -0
  31. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +34 -0
  32. data/lib/mongoid/criteria/queryable/extensions/date.rb +63 -0
  33. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +53 -0
  34. data/lib/mongoid/criteria/queryable/extensions/hash.rb +200 -0
  35. data/lib/mongoid/criteria/queryable/extensions/nil_class.rb +86 -0
  36. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +90 -0
  37. data/lib/mongoid/criteria/queryable/extensions/object.rb +206 -0
  38. data/lib/mongoid/criteria/queryable/extensions/range.rb +70 -0
  39. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +79 -0
  40. data/lib/mongoid/criteria/queryable/extensions/set.rb +34 -0
  41. data/lib/mongoid/criteria/queryable/extensions/string.rb +137 -0
  42. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +79 -0
  43. data/lib/mongoid/criteria/queryable/extensions/time.rb +60 -0
  44. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +54 -0
  45. data/lib/mongoid/criteria/queryable/forwardable.rb +65 -0
  46. data/lib/mongoid/criteria/queryable/key.rb +103 -0
  47. data/lib/mongoid/criteria/queryable/macroable.rb +27 -0
  48. data/lib/mongoid/criteria/queryable/mergeable.rb +271 -0
  49. data/lib/mongoid/criteria/queryable/optional.rb +429 -0
  50. data/lib/mongoid/criteria/queryable/options.rb +153 -0
  51. data/lib/mongoid/criteria/queryable/pipeline.rb +111 -0
  52. data/lib/mongoid/criteria/queryable/selectable.rb +662 -0
  53. data/lib/mongoid/criteria/queryable/selector.rb +212 -0
  54. data/lib/mongoid/criteria/queryable/smash.rb +104 -0
  55. data/lib/mongoid/document.rb +30 -37
  56. data/lib/mongoid/errors.rb +2 -0
  57. data/lib/mongoid/errors/ambiguous_relationship.rb +1 -1
  58. data/lib/mongoid/errors/in_memory_collation_not_supported.rb +1 -1
  59. data/lib/mongoid/errors/invalid_field.rb +2 -2
  60. data/lib/mongoid/errors/invalid_persistence_option.rb +29 -0
  61. data/lib/mongoid/errors/invalid_relation.rb +66 -0
  62. data/lib/mongoid/evolvable.rb +1 -1
  63. data/lib/mongoid/extensions.rb +0 -4
  64. data/lib/mongoid/extensions/big_decimal.rb +17 -8
  65. data/lib/mongoid/extensions/date.rb +4 -1
  66. data/lib/mongoid/extensions/decimal128.rb +3 -3
  67. data/lib/mongoid/extensions/hash.rb +1 -0
  68. data/lib/mongoid/extensions/string.rb +4 -3
  69. data/lib/mongoid/extensions/time.rb +4 -1
  70. data/lib/mongoid/fields/validators/macro.rb +18 -0
  71. data/lib/mongoid/findable.rb +2 -2
  72. data/lib/mongoid/indexable.rb +15 -13
  73. data/lib/mongoid/interceptable.rb +5 -22
  74. data/lib/mongoid/matchable.rb +13 -7
  75. data/lib/mongoid/matchable/all.rb +2 -2
  76. data/lib/mongoid/matchable/and.rb +3 -3
  77. data/lib/mongoid/matchable/default.rb +2 -2
  78. data/lib/mongoid/matchable/elem_match.rb +28 -0
  79. data/lib/mongoid/matchable/exists.rb +2 -2
  80. data/lib/mongoid/matchable/gt.rb +4 -2
  81. data/lib/mongoid/matchable/gte.rb +4 -2
  82. data/lib/mongoid/matchable/in.rb +2 -2
  83. data/lib/mongoid/matchable/lt.rb +4 -2
  84. data/lib/mongoid/matchable/lte.rb +4 -2
  85. data/lib/mongoid/matchable/ne.rb +2 -2
  86. data/lib/mongoid/matchable/nin.rb +2 -2
  87. data/lib/mongoid/matchable/or.rb +3 -3
  88. data/lib/mongoid/matchable/regexp.rb +3 -3
  89. data/lib/mongoid/matchable/size.rb +2 -2
  90. data/lib/mongoid/persistable.rb +3 -5
  91. data/lib/mongoid/persistable/creatable.rb +2 -2
  92. data/lib/mongoid/persistable/deletable.rb +1 -1
  93. data/lib/mongoid/persistable/settable.rb +1 -1
  94. data/lib/mongoid/persistable/updatable.rb +5 -12
  95. data/lib/mongoid/persistable/upsertable.rb +1 -1
  96. data/lib/mongoid/persistence_context.rb +215 -0
  97. data/lib/mongoid/query_cache.rb +3 -6
  98. data/lib/mongoid/relations/accessors.rb +3 -0
  99. data/lib/mongoid/relations/auto_save.rb +12 -4
  100. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +4 -4
  101. data/lib/mongoid/relations/counter_cache.rb +15 -5
  102. data/lib/mongoid/relations/eager.rb +6 -11
  103. data/lib/mongoid/relations/eager/base.rb +3 -3
  104. data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +2 -2
  105. data/lib/mongoid/relations/eager/has_many.rb +1 -1
  106. data/lib/mongoid/relations/embedded/batchable.rb +12 -36
  107. data/lib/mongoid/relations/embedded/in.rb +13 -1
  108. data/lib/mongoid/relations/embedded/many.rb +28 -10
  109. data/lib/mongoid/relations/embedded/one.rb +14 -1
  110. data/lib/mongoid/relations/macros.rb +9 -1
  111. data/lib/mongoid/relations/metadata.rb +3 -3
  112. data/lib/mongoid/relations/options.rb +2 -2
  113. data/lib/mongoid/relations/proxy.rb +1 -31
  114. data/lib/mongoid/relations/referenced/in.rb +19 -10
  115. data/lib/mongoid/relations/referenced/many.rb +23 -17
  116. data/lib/mongoid/relations/referenced/many_to_many.rb +20 -13
  117. data/lib/mongoid/relations/referenced/one.rb +15 -1
  118. data/lib/mongoid/relations/synchronization.rb +11 -11
  119. data/lib/mongoid/relations/touchable.rb +6 -3
  120. data/lib/mongoid/reloadable.rb +1 -1
  121. data/lib/mongoid/serializable.rb +1 -1
  122. data/lib/mongoid/traversable.rb +1 -1
  123. data/lib/mongoid/validatable/uniqueness.rb +1 -2
  124. data/lib/mongoid/version.rb +1 -1
  125. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +14 -3
  126. data/spec/app/models/album.rb +5 -1
  127. data/spec/app/models/artist.rb +21 -0
  128. data/spec/app/models/book.rb +2 -1
  129. data/spec/app/models/dokument.rb +1 -0
  130. data/spec/app/models/ordered_post.rb +5 -0
  131. data/spec/app/models/oscar.rb +1 -2
  132. data/spec/app/models/page.rb +1 -1
  133. data/spec/app/models/person.rb +3 -3
  134. data/spec/app/models/princess.rb +2 -0
  135. data/spec/app/models/record.rb +1 -0
  136. data/spec/app/models/subscription.rb +1 -0
  137. data/spec/app/models/thing.rb +1 -1
  138. data/spec/config/mongoid.yml +15 -0
  139. data/spec/mongoid/atomic/modifiers_spec.rb +17 -17
  140. data/spec/mongoid/atomic_spec.rb +17 -17
  141. data/spec/mongoid/attributes/nested_spec.rb +14 -14
  142. data/spec/mongoid/attributes/readonly_spec.rb +87 -44
  143. data/spec/mongoid/attributes_spec.rb +90 -5
  144. data/spec/mongoid/cacheable_spec.rb +112 -0
  145. data/spec/mongoid/changeable_spec.rb +58 -0
  146. data/spec/mongoid/clients/factory_spec.rb +31 -3
  147. data/spec/mongoid/clients/options_spec.rb +382 -96
  148. data/spec/mongoid/clients_spec.rb +243 -101
  149. data/spec/mongoid/composable_spec.rb +7 -0
  150. data/spec/mongoid/config_spec.rb +67 -11
  151. data/spec/mongoid/contextual/atomic_spec.rb +3 -3
  152. data/spec/mongoid/contextual/mongo_spec.rb +165 -20
  153. data/spec/mongoid/contextual/none_spec.rb +15 -0
  154. data/spec/mongoid/copyable_spec.rb +13 -4
  155. data/spec/mongoid/criteria/modifiable_spec.rb +239 -7
  156. data/spec/mongoid/criteria/options_spec.rb +29 -0
  157. data/spec/mongoid/criteria/queryable/aggregable_spec.rb +370 -0
  158. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +523 -0
  159. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +59 -0
  160. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +58 -0
  161. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +213 -0
  162. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +330 -0
  163. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +405 -0
  164. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +58 -0
  165. data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +65 -0
  166. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +327 -0
  167. data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +65 -0
  168. data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +77 -0
  169. data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +108 -0
  170. data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +309 -0
  171. data/spec/mongoid/{extensions/origin → criteria/queryable/extensions}/regexp_raw_spec.rb +2 -2
  172. data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +90 -0
  173. data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +39 -0
  174. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +302 -0
  175. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +167 -0
  176. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +376 -0
  177. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +347 -0
  178. data/spec/mongoid/criteria/queryable/forwardable_spec.rb +87 -0
  179. data/spec/mongoid/criteria/queryable/key_spec.rb +52 -0
  180. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +49 -0
  181. data/spec/mongoid/criteria/queryable/optional_spec.rb +1799 -0
  182. data/spec/mongoid/criteria/queryable/options_spec.rb +360 -0
  183. data/spec/mongoid/criteria/queryable/pipeline_spec.rb +200 -0
  184. data/spec/mongoid/criteria/queryable/queryable_spec.rb +137 -0
  185. data/spec/mongoid/criteria/queryable/selectable_spec.rb +4174 -0
  186. data/spec/mongoid/criteria/queryable/selector_spec.rb +844 -0
  187. data/spec/mongoid/criteria/queryable/smash_spec.rb +30 -0
  188. data/spec/mongoid/criteria_spec.rb +152 -21
  189. data/spec/mongoid/document_spec.rb +37 -88
  190. data/spec/mongoid/errors/invalid_relation_spec.rb +37 -0
  191. data/spec/mongoid/errors/mongoid_error_spec.rb +6 -3
  192. data/spec/mongoid/extensions/big_decimal_spec.rb +320 -18
  193. data/spec/mongoid/extensions/boolean_spec.rb +14 -0
  194. data/spec/mongoid/extensions/date_spec.rb +2 -6
  195. data/spec/mongoid/extensions/date_time_spec.rb +2 -6
  196. data/spec/mongoid/extensions/decimal128_spec.rb +1 -1
  197. data/spec/mongoid/extensions/float_spec.rb +8 -1
  198. data/spec/mongoid/extensions/hash_spec.rb +15 -0
  199. data/spec/mongoid/extensions/integer_spec.rb +8 -1
  200. data/spec/mongoid/extensions/object_spec.rb +11 -0
  201. data/spec/mongoid/extensions/string_spec.rb +21 -0
  202. data/spec/mongoid/extensions/time_spec.rb +2 -6
  203. data/spec/mongoid/extensions/time_with_zone_spec.rb +2 -6
  204. data/spec/mongoid/findable_spec.rb +46 -1
  205. data/spec/mongoid/indexable_spec.rb +15 -3
  206. data/spec/mongoid/interceptable_spec.rb +68 -10
  207. data/spec/mongoid/matchable/all_spec.rb +4 -4
  208. data/spec/mongoid/matchable/and_spec.rb +10 -10
  209. data/spec/mongoid/matchable/default_spec.rb +12 -12
  210. data/spec/mongoid/matchable/elem_match_spec.rb +86 -0
  211. data/spec/mongoid/matchable/exists_spec.rb +5 -5
  212. data/spec/mongoid/matchable/gt_spec.rb +18 -7
  213. data/spec/mongoid/matchable/gte_spec.rb +17 -7
  214. data/spec/mongoid/matchable/in_spec.rb +5 -5
  215. data/spec/mongoid/matchable/lt_spec.rb +18 -7
  216. data/spec/mongoid/matchable/lte_spec.rb +18 -7
  217. data/spec/mongoid/matchable/ne_spec.rb +5 -5
  218. data/spec/mongoid/matchable/nin_spec.rb +5 -5
  219. data/spec/mongoid/matchable/or_spec.rb +7 -7
  220. data/spec/mongoid/matchable/regexp_spec.rb +5 -5
  221. data/spec/mongoid/matchable/size_spec.rb +3 -3
  222. data/spec/mongoid/matchable_spec.rb +173 -53
  223. data/spec/mongoid/persistable/creatable_spec.rb +7 -2
  224. data/spec/mongoid/persistable/deletable_spec.rb +16 -1
  225. data/spec/mongoid/persistable/destroyable_spec.rb +6 -2
  226. data/spec/mongoid/persistable/savable_spec.rb +35 -30
  227. data/spec/mongoid/persistable/settable_spec.rb +45 -29
  228. data/spec/mongoid/persistable/updatable_spec.rb +184 -5
  229. data/spec/mongoid/persistence_context_spec.rb +680 -0
  230. data/spec/mongoid/positional_spec.rb +10 -10
  231. data/spec/mongoid/query_cache_spec.rb +89 -0
  232. data/spec/mongoid/relations/accessors_spec.rb +1 -1
  233. data/spec/mongoid/relations/auto_save_spec.rb +39 -6
  234. data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +4 -4
  235. data/spec/mongoid/relations/builders_spec.rb +37 -10
  236. data/spec/mongoid/relations/counter_cache_spec.rb +64 -3
  237. data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +16 -0
  238. data/spec/mongoid/relations/eager_spec.rb +40 -0
  239. data/spec/mongoid/relations/embedded/many_spec.rb +63 -47
  240. data/spec/mongoid/relations/embedded/one_spec.rb +2 -1
  241. data/spec/mongoid/relations/macros_spec.rb +395 -7
  242. data/spec/mongoid/relations/metadata_spec.rb +15 -1
  243. data/spec/mongoid/relations/proxy_spec.rb +27 -1
  244. data/spec/mongoid/relations/referenced/in_spec.rb +41 -1
  245. data/spec/mongoid/relations/referenced/many_spec.rb +13 -25
  246. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +14 -26
  247. data/spec/mongoid/relations/synchronization_spec.rb +48 -2
  248. data/spec/mongoid/relations/touchable_spec.rb +40 -0
  249. data/spec/mongoid/reloadable_spec.rb +51 -0
  250. data/spec/mongoid/serializable_spec.rb +0 -50
  251. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  252. data/spec/mongoid/validatable/uniqueness_spec.rb +18 -9
  253. data/spec/mongoid/validatable_spec.rb +16 -0
  254. data/spec/spec_helper.rb +20 -11
  255. metadata +524 -469
  256. checksums.yaml.gz.sig +0 -0
  257. data.tar.gz.sig +0 -0
  258. data/lib/mongoid/clients/thread_options.rb +0 -19
  259. data/lib/mongoid/extensions/origin/regexp_raw.rb +0 -43
  260. metadata.gz.sig +0 -0
@@ -17,8 +17,8 @@ describe Mongoid::Positional do
17
17
  "children.0.field" => "value",
18
18
  "children.0.children.1.children.3.field" => "value"
19
19
  },
20
- "$push" => {
21
- "children.0.children.1.children.3.fields" => {'$each' => [ "value", "value" ]}
20
+ "$pushAll" => {
21
+ "children.0.children.1.children.3.fields" => [ "value", "value" ]
22
22
  }
23
23
  }
24
24
  end
@@ -113,8 +113,8 @@ describe Mongoid::Positional do
113
113
  "children.$.field" => "value",
114
114
  "children.0.children.1.children.3.field" => "value"
115
115
  },
116
- "$push" => {
117
- "children.0.children.1.children.3.fields" => { '$each' => [ "value", "value" ] }
116
+ "$pushAll" => {
117
+ "children.0.children.1.children.3.fields" => [ "value", "value" ]
118
118
  }
119
119
  }
120
120
  end
@@ -141,8 +141,8 @@ describe Mongoid::Positional do
141
141
  "children.0.field" => "value",
142
142
  "children.0.children.1.children.3.field" => "value"
143
143
  },
144
- "$push" => {
145
- "children.0.children.1.children.3.fields" => { '$each' => [ "value", "value" ] }
144
+ "$pushAll" => {
145
+ "children.0.children.1.children.3.fields" => [ "value", "value" ]
146
146
  }
147
147
  }
148
148
  end
@@ -170,8 +170,8 @@ describe Mongoid::Positional do
170
170
  "children.$.field" => "value",
171
171
  "children.0.children.1.children.3.field" => "value"
172
172
  },
173
- "$push" => {
174
- "children.0.children.1.children.3.fields" => { '$each' => [ "value", "value" ] }
173
+ "$pushAll" => {
174
+ "children.0.children.1.children.3.fields" => [ "value", "value" ]
175
175
  }
176
176
  }
177
177
  end
@@ -203,8 +203,8 @@ describe Mongoid::Positional do
203
203
  "children.$.field" => "value",
204
204
  "children.0.children.1.children.3.field" => "value"
205
205
  },
206
- "$push" => {
207
- "children.0.children.1.children.3.fields" => { '$each' => [ "value", "value" ] }
206
+ "$pushAll" => {
207
+ "children.0.children.1.children.3.fields" => [ "value", "value" ]
208
208
  }
209
209
  }
210
210
  end
@@ -7,6 +7,95 @@ describe Mongoid::QueryCache do
7
7
  Mongoid::QueryCache.cache { spec.run }
8
8
  end
9
9
 
10
+ context 'when iterating over objects sharing the same base' do
11
+
12
+ let(:server) do
13
+ relations.first.mongo_client.cluster.next_primary
14
+ end
15
+
16
+ before do
17
+ person = Person.create
18
+ 3.times do
19
+ person.send(relation).create
20
+ end
21
+ person.save
22
+ end
23
+
24
+ let!(:relations) do
25
+ Person.first.send(relation).to_a
26
+ end
27
+
28
+ context 'when the association is has-many' do
29
+
30
+ let(:relation) do
31
+ :posts
32
+ end
33
+
34
+ context 'when query cache is disabled' do
35
+
36
+ before do
37
+ Mongoid::QueryCache.enabled = false
38
+ end
39
+
40
+ it 'queries for each access to the base' do
41
+ expect(server).to receive(:with_connection).exactly(relations.size).times.and_call_original
42
+ relations.each do |object|
43
+ object.person
44
+ end
45
+ end
46
+ end
47
+
48
+ context 'when query cache is enabled' do
49
+
50
+ before do
51
+ Mongoid::QueryCache.enabled = true
52
+ end
53
+
54
+ it 'queries only once for the base' do
55
+ expect(server).to receive(:with_connection).exactly(1).times.and_call_original
56
+ relations.each do |object|
57
+ object.person
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ context 'when the association is embeds-many' do
64
+
65
+ let(:relation) do
66
+ :symptoms
67
+ end
68
+
69
+ context 'when query cache is disabled' do
70
+
71
+ before do
72
+ Mongoid::QueryCache.enabled = false
73
+ end
74
+
75
+ it 'does not query for access to the base' do
76
+ expect(server).to receive(:context).exactly(0).times.and_call_original
77
+ relations.each do |object|
78
+ object.person
79
+ end
80
+ end
81
+ end
82
+
83
+ context 'when query cache is enabled' do
84
+
85
+ before do
86
+ Mongoid::QueryCache.enabled = true
87
+ end
88
+
89
+ it 'does not query for access to the base' do
90
+ expect(server).to receive(:context).exactly(0).times.and_call_original
91
+ relations.each do |object|
92
+ object.person
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+
10
99
  context "when querying for a single document" do
11
100
 
12
101
  [ :first, :one, :last ].each do |method|
@@ -728,7 +728,7 @@ describe Mongoid::Relations::Accessors do
728
728
  game.save
729
729
  end
730
730
 
731
- it "keeps the the foreign key as ObjectID" do
731
+ it "keeps the foreign key as ObjectID" do
732
732
  expect(game.reload.person_id).to eq(person.id)
733
733
  end
734
734
  end
@@ -70,13 +70,44 @@ describe Mongoid::Relations::AutoSave do
70
70
 
71
71
  context "when saving a new parent document" do
72
72
 
73
- before do
74
- person.drugs << drug
75
- person.save
73
+ context 'when persistence options are not set on the parent' do
74
+ before do
75
+ person.drugs << drug
76
+ person.save
77
+ end
78
+
79
+ it "saves the relation" do
80
+ expect(drug).to be_persisted
81
+ end
76
82
  end
77
83
 
78
- it "saves the relation" do
79
- expect(drug).to be_persisted
84
+ context 'when persistence options are set on the parent' do
85
+
86
+ let(:other_database) do
87
+ :other
88
+ end
89
+
90
+ after do
91
+ Person.with(database: other_database) do |person_class|
92
+ person_class.delete_all
93
+ end
94
+ Drug.with(database: other_database) do |drug_class|
95
+ drug_class.delete_all
96
+ end
97
+ end
98
+
99
+ before do
100
+ person.with(database: other_database) do |per|
101
+ per.drugs << drug
102
+ per.save
103
+ end
104
+ end
105
+
106
+ it 'saves the relation with the persistence options' do
107
+ Drug.with(database: other_database) do |drug_class|
108
+ expect(drug_class.count).to eq(1)
109
+ end
110
+ end
80
111
  end
81
112
  end
82
113
 
@@ -160,7 +191,9 @@ describe Mongoid::Relations::AutoSave do
160
191
  it "sends one insert" do
161
192
  account.name = "account"
162
193
  expect_query(1) do
163
- person.with(write: {w:0}).save
194
+ person.with(write: {w:0}) do |_person|
195
+ _person.save
196
+ end
164
197
  end
165
198
  end
166
199
  end
@@ -43,11 +43,11 @@ describe Mongoid::Relations::Bindings::Referenced::ManyToMany do
43
43
  end
44
44
 
45
45
  it "syncs the base" do
46
- expect(person).to be_synced("preference_ids")
46
+ expect(person._synced?("preference_ids")).to be(true)
47
47
  end
48
48
 
49
49
  it "syncs the inverse" do
50
- expect(preference_two).to be_synced("person_ids")
50
+ expect(preference_two._synced?("person_ids")).to be(true)
51
51
  end
52
52
  end
53
53
 
@@ -98,11 +98,11 @@ describe Mongoid::Relations::Bindings::Referenced::ManyToMany do
98
98
  end
99
99
 
100
100
  it "syncs the base" do
101
- expect(person).to be_synced("preference_ids")
101
+ expect(person._synced?("preference_ids")).to be(true)
102
102
  end
103
103
 
104
104
  it "syncs the inverse" do
105
- expect(preference).to be_synced("person_ids")
105
+ expect(preference._synced?("person_ids")).to be(true)
106
106
  end
107
107
  end
108
108
 
@@ -185,20 +185,47 @@ describe Mongoid::Relations::Builders do
185
185
 
186
186
  context "when a document already exists" do
187
187
 
188
- let!(:game_two) do
189
- person.create_game(name: "Skyrim")
190
- end
188
+ context "when the relation belongs_to is already set" do
191
189
 
192
- it "replaces the existing document" do
193
- expect(person.game).to eq(game_two)
194
- end
190
+ let!(:game_one) do
191
+ game = person.create_game(name: "Starcraft")
192
+ game.person = person
193
+ end
194
+
195
+ let!(:game_two) do
196
+ person.create_game(name: "Skyrim")
197
+ end
198
+
199
+ it "replaces the existing document" do
200
+ expect(person.game).to eq(game_two)
201
+ end
202
+
203
+ it "persists the change" do
204
+ expect(person.game(true)).to eq(game_two)
205
+ end
195
206
 
196
- it "persists the change" do
197
- expect(person.game(true)).to eq(game_two)
207
+ it "removes the old document from the database" do
208
+ expect(Game.collection.find.count).to eq(1)
209
+ end
198
210
  end
199
211
 
200
- it "removes the old document from the database" do
201
- expect(Game.collection.find.count).to eq(1)
212
+ context 'when the relation belongs_to is not already set' do
213
+
214
+ let!(:game_two) do
215
+ person.create_game(name: "Skyrim")
216
+ end
217
+
218
+ it "replaces the existing document" do
219
+ expect(person.game).to eq(game_two)
220
+ end
221
+
222
+ it "persists the change" do
223
+ expect(person.game(true)).to eq(game_two)
224
+ end
225
+
226
+ it "removes the old document from the database" do
227
+ expect(Game.collection.find.count).to eq(1)
228
+ end
202
229
  end
203
230
  end
204
231
  end
@@ -34,7 +34,7 @@ describe Mongoid::Relations::CounterCache do
34
34
  it "expect to raise an error" do
35
35
  expect {
36
36
  person.reset_counters(:not_exist)
37
- }.to raise_error
37
+ }.to raise_error(NoMethodError)
38
38
  end
39
39
  end
40
40
 
@@ -85,6 +85,26 @@ describe Mongoid::Relations::CounterCache do
85
85
  expect(subscription.reload[:packs_count]).to eq(1)
86
86
  end
87
87
  end
88
+
89
+ context 'when there are persistence options set' do
90
+
91
+ let(:subscription) do
92
+ Subscription.new
93
+ end
94
+
95
+ before do
96
+ subscription.with(collection: 'other') do |sub|
97
+ sub.save
98
+ sub.packs.create
99
+ end
100
+ end
101
+
102
+ it 'applies the persistence options when resetting the counter' do
103
+ subscription.with(collection: 'other') do |sub|
104
+ expect(sub.reload[:packs_count]).to eq(1)
105
+ end
106
+ end
107
+ end
88
108
  end
89
109
 
90
110
  describe ".reset_counters" do
@@ -111,7 +131,7 @@ describe Mongoid::Relations::CounterCache do
111
131
  it "expect to raise an error" do
112
132
  expect {
113
133
  Person.reset_counters "1", :drugs
114
- }.to raise_error
134
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
115
135
  end
116
136
  end
117
137
 
@@ -124,7 +144,7 @@ describe Mongoid::Relations::CounterCache do
124
144
  it "expect to raise an error" do
125
145
  expect {
126
146
  Person.reset_counters person.id, :not_exist
127
- }.to raise_error
147
+ }.to raise_error(NoMethodError)
128
148
  end
129
149
  end
130
150
 
@@ -256,6 +276,26 @@ describe Mongoid::Relations::CounterCache do
256
276
  expect(person.reload.drugs_count).to eq(3)
257
277
  end
258
278
  end
279
+
280
+ context 'when there are persistence options set' do
281
+
282
+ let(:person) do
283
+ Person.new
284
+ end
285
+
286
+ before do
287
+ person.with(collection: 'other') do |per|
288
+ per.save
289
+ per.drugs.create
290
+ end
291
+ end
292
+
293
+ it 'applies the persistence options when resetting the counter' do
294
+ person.with(collection: 'other') do |per|
295
+ expect(per.drugs_count).to eq(1)
296
+ end
297
+ end
298
+ end
259
299
  end
260
300
 
261
301
  describe "#decrement_counter" do
@@ -286,6 +326,27 @@ describe Mongoid::Relations::CounterCache do
286
326
  expect(person.reload.drugs_count).to eq(0)
287
327
  end
288
328
  end
329
+
330
+ context 'when there are persistence options set' do
331
+
332
+ let(:person) do
333
+ Person.new
334
+ end
335
+
336
+ before do
337
+ person.with(collection: 'other') do |per|
338
+ per.save
339
+ drug = per.drugs.create
340
+ drug.destroy
341
+ end
342
+ end
343
+
344
+ it 'applies the persistence options when resetting the counter' do
345
+ person.with(collection: 'other') do |per|
346
+ expect(per.reload.drugs_count).to eq(0)
347
+ end
348
+ end
349
+ end
289
350
  end
290
351
 
291
352
  describe "#add_counter_cache_callbacks" do
@@ -113,5 +113,21 @@ describe Mongoid::Relations::Eager::HasAndBelongsToMany do
113
113
  end
114
114
  end
115
115
  end
116
+
117
+ context "when some related documents no longer exist" do
118
+ before do
119
+ # Deleting the first one to meet Builders::Referenced::ManyToMany#query?
120
+ House.collection.find(_id: Person.first.house_ids.first).delete_one
121
+ end
122
+
123
+ it "does not accidentally trigger an extra query" do
124
+ expect_query(2) do
125
+ Person.asc(:_id).includes(:houses).each do |person|
126
+ expect(person.houses).to_not be_nil
127
+ expect(person.houses.length).to be(2)
128
+ end
129
+ end
130
+ end
131
+ end
116
132
  end
117
133
  end
@@ -181,6 +181,46 @@ describe Mongoid::Relations::Eager do
181
181
  expect(Mongoid::Relations::Eager::HasAndBelongsToMany).to receive(:new).with([houses_metadata], docs).once.and_call_original
182
182
  context.eager_load(docs)
183
183
  end
184
+
185
+ context 'when one of the eager loading definitions is nested' do
186
+
187
+ before do
188
+ class User
189
+ include Mongoid::Document
190
+ end
191
+
192
+ class Unit
193
+ include Mongoid::Document
194
+ end
195
+
196
+ class Booking
197
+ include Mongoid::Document
198
+ belongs_to :unit
199
+ has_many :vouchers
200
+ end
201
+
202
+ class Voucher
203
+ include Mongoid::Document
204
+ belongs_to :booking
205
+ belongs_to :created_by, class_name: 'User'
206
+ end
207
+ end
208
+
209
+ it 'successfully loads all relations' do
210
+ user = User.create
211
+ unit = Unit.create
212
+ booking = Booking.create(unit: unit)
213
+ Voucher.create(booking: booking, created_by: user)
214
+
215
+ vouchers = Voucher.includes(:created_by, booking: [:unit])
216
+
217
+ vouchers.each do |voucher|
218
+ expect(voucher.created_by).to eql(user)
219
+ expect(voucher.booking).to eql(booking)
220
+ expect(voucher.booking.unit).to eql(unit)
221
+ end
222
+ end
223
+ end
184
224
  end
185
225
 
186
226
  context "when including two of the same relation type" do