mongoid 7.5.4 → 8.1.3

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 (421) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +3 -3
  4. data/README.md +6 -6
  5. data/lib/config/locales/en.yml +92 -43
  6. data/lib/mongoid/association/accessors.rb +40 -11
  7. data/lib/mongoid/association/bindable.rb +50 -2
  8. data/lib/mongoid/association/builders.rb +5 -3
  9. data/lib/mongoid/association/constrainable.rb +0 -1
  10. data/lib/mongoid/association/eager_loadable.rb +29 -7
  11. data/lib/mongoid/association/embedded/batchable.rb +34 -11
  12. data/lib/mongoid/association/embedded/cyclic.rb +1 -1
  13. data/lib/mongoid/association/embedded/embedded_in/binding.rb +24 -2
  14. data/lib/mongoid/association/embedded/embedded_in/buildable.rb +2 -2
  15. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +4 -3
  16. data/lib/mongoid/association/embedded/embedded_in.rb +3 -2
  17. data/lib/mongoid/association/embedded/embeds_many/binding.rb +1 -0
  18. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +4 -3
  19. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +69 -45
  20. data/lib/mongoid/association/embedded/embeds_many.rb +2 -2
  21. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +19 -5
  22. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +24 -5
  23. data/lib/mongoid/association/embedded/embeds_one.rb +3 -3
  24. data/lib/mongoid/association/macros.rb +8 -1
  25. data/lib/mongoid/association/many.rb +11 -7
  26. data/lib/mongoid/association/nested/many.rb +5 -4
  27. data/lib/mongoid/association/nested/nested_buildable.rb +4 -4
  28. data/lib/mongoid/association/nested/one.rb +45 -7
  29. data/lib/mongoid/association/one.rb +2 -2
  30. data/lib/mongoid/association/options.rb +9 -9
  31. data/lib/mongoid/association/proxy.rb +15 -4
  32. data/lib/mongoid/association/referenced/auto_save.rb +4 -3
  33. data/lib/mongoid/association/referenced/belongs_to/binding.rb +1 -0
  34. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +1 -1
  35. data/lib/mongoid/association/referenced/belongs_to/proxy.rb +5 -6
  36. data/lib/mongoid/association/referenced/belongs_to.rb +2 -2
  37. data/lib/mongoid/association/referenced/counter_cache.rb +10 -10
  38. data/lib/mongoid/association/referenced/eager.rb +2 -2
  39. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +70 -13
  40. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +6 -3
  41. data/lib/mongoid/association/referenced/has_many/enumerable.rb +22 -30
  42. data/lib/mongoid/association/referenced/has_many/proxy.rb +29 -19
  43. data/lib/mongoid/association/referenced/has_many.rb +3 -3
  44. data/lib/mongoid/association/referenced/has_one/buildable.rb +1 -1
  45. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +5 -5
  46. data/lib/mongoid/association/referenced/has_one/proxy.rb +9 -12
  47. data/lib/mongoid/association/referenced/has_one.rb +3 -3
  48. data/lib/mongoid/association/referenced/syncable.rb +4 -4
  49. data/lib/mongoid/association/reflections.rb +4 -4
  50. data/lib/mongoid/association/relatable.rb +44 -10
  51. data/lib/mongoid/association.rb +5 -5
  52. data/lib/mongoid/atomic/modifiers.rb +2 -2
  53. data/lib/mongoid/atomic.rb +7 -0
  54. data/lib/mongoid/attributes/dynamic.rb +4 -4
  55. data/lib/mongoid/attributes/nested.rb +6 -6
  56. data/lib/mongoid/attributes/processing.rb +37 -6
  57. data/lib/mongoid/attributes/projector.rb +2 -2
  58. data/lib/mongoid/attributes/readonly.rb +3 -3
  59. data/lib/mongoid/attributes.rb +51 -42
  60. data/lib/mongoid/changeable.rb +147 -14
  61. data/lib/mongoid/clients/options.rb +5 -1
  62. data/lib/mongoid/clients/sessions.rb +2 -14
  63. data/lib/mongoid/clients/storage_options.rb +2 -5
  64. data/lib/mongoid/clients/validators/storage.rb +3 -15
  65. data/lib/mongoid/collection_configurable.rb +58 -0
  66. data/lib/mongoid/composable.rb +2 -0
  67. data/lib/mongoid/config/defaults.rb +60 -0
  68. data/lib/mongoid/config/options.rb +3 -0
  69. data/lib/mongoid/config/validators/async_query_executor.rb +24 -0
  70. data/lib/mongoid/config/validators/client.rb +6 -6
  71. data/lib/mongoid/config/validators.rb +1 -0
  72. data/lib/mongoid/config.rb +153 -18
  73. data/lib/mongoid/contextual/aggregable/memory.rb +24 -16
  74. data/lib/mongoid/contextual/aggregable/mongo.rb +5 -5
  75. data/lib/mongoid/contextual/aggregable/none.rb +1 -1
  76. data/lib/mongoid/contextual/atomic.rb +1 -1
  77. data/lib/mongoid/contextual/geo_near.rb +7 -7
  78. data/lib/mongoid/contextual/map_reduce.rb +2 -2
  79. data/lib/mongoid/contextual/memory.rb +285 -58
  80. data/lib/mongoid/contextual/mongo/documents_loader.rb +177 -0
  81. data/lib/mongoid/contextual/mongo.rb +540 -346
  82. data/lib/mongoid/contextual/none.rb +193 -20
  83. data/lib/mongoid/contextual/queryable.rb +1 -1
  84. data/lib/mongoid/contextual.rb +14 -2
  85. data/lib/mongoid/copyable.rb +32 -8
  86. data/lib/mongoid/criteria/findable.rb +8 -5
  87. data/lib/mongoid/criteria/includable.rb +27 -22
  88. data/lib/mongoid/criteria/marshalable.rb +10 -2
  89. data/lib/mongoid/criteria/permission.rb +1 -1
  90. data/lib/mongoid/criteria/queryable/aggregable.rb +2 -2
  91. data/lib/mongoid/criteria/queryable/extensions/array.rb +3 -16
  92. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +25 -4
  93. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +2 -2
  94. data/lib/mongoid/criteria/queryable/extensions/date.rb +6 -1
  95. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +6 -1
  96. data/lib/mongoid/criteria/queryable/extensions/hash.rb +1 -17
  97. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -9
  98. data/lib/mongoid/criteria/queryable/extensions/object.rb +2 -1
  99. data/lib/mongoid/criteria/queryable/extensions/range.rb +13 -5
  100. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +3 -3
  101. data/lib/mongoid/criteria/queryable/extensions/set.rb +1 -1
  102. data/lib/mongoid/criteria/queryable/extensions/string.rb +4 -14
  103. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +4 -12
  104. data/lib/mongoid/criteria/queryable/extensions/time.rb +6 -1
  105. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +6 -1
  106. data/lib/mongoid/criteria/queryable/key.rb +4 -4
  107. data/lib/mongoid/criteria/queryable/mergeable.rb +1 -1
  108. data/lib/mongoid/criteria/queryable/optional.rb +11 -17
  109. data/lib/mongoid/criteria/queryable/options.rb +2 -2
  110. data/lib/mongoid/criteria/queryable/pipeline.rb +1 -1
  111. data/lib/mongoid/criteria/queryable/selectable.rb +47 -38
  112. data/lib/mongoid/criteria/queryable/selector.rb +92 -7
  113. data/lib/mongoid/criteria/queryable/smash.rb +40 -7
  114. data/lib/mongoid/criteria/queryable.rb +12 -7
  115. data/lib/mongoid/criteria/scopable.rb +2 -2
  116. data/lib/mongoid/criteria/translator.rb +45 -0
  117. data/lib/mongoid/criteria.rb +20 -40
  118. data/lib/mongoid/deprecable.rb +37 -0
  119. data/lib/mongoid/deprecation.rb +25 -0
  120. data/lib/mongoid/document.rb +127 -35
  121. data/lib/mongoid/equality.rb +8 -8
  122. data/lib/mongoid/errors/create_collection_failure.rb +33 -0
  123. data/lib/mongoid/errors/document_not_found.rb +10 -6
  124. data/lib/mongoid/errors/drop_collection_failure.rb +27 -0
  125. data/lib/mongoid/errors/immutable_attribute.rb +26 -0
  126. data/lib/mongoid/errors/invalid_async_query_executor.rb +25 -0
  127. data/lib/mongoid/errors/invalid_config_option.rb +1 -1
  128. data/lib/mongoid/errors/invalid_dependent_strategy.rb +1 -1
  129. data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +23 -0
  130. data/lib/mongoid/errors/invalid_field.rb +6 -2
  131. data/lib/mongoid/errors/invalid_field_type.rb +26 -0
  132. data/lib/mongoid/errors/invalid_global_executor_concurrency.rb +22 -0
  133. data/lib/mongoid/errors/invalid_relation.rb +1 -1
  134. data/lib/mongoid/errors/invalid_relation_option.rb +1 -1
  135. data/lib/mongoid/errors/invalid_session_use.rb +1 -1
  136. data/lib/mongoid/errors/invalid_storage_options.rb +1 -1
  137. data/lib/mongoid/errors/invalid_storage_parent.rb +2 -0
  138. data/lib/mongoid/errors/mongoid_error.rb +3 -3
  139. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +1 -1
  140. data/lib/mongoid/errors/no_client_database.rb +1 -1
  141. data/lib/mongoid/errors/no_client_hosts.rb +1 -1
  142. data/lib/mongoid/errors/readonly_attribute.rb +1 -1
  143. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +1 -1
  144. data/lib/mongoid/errors/unknown_attribute.rb +1 -1
  145. data/lib/mongoid/errors.rb +6 -3
  146. data/lib/mongoid/extensions/array.rb +9 -7
  147. data/lib/mongoid/extensions/big_decimal.rb +33 -10
  148. data/lib/mongoid/extensions/binary.rb +42 -0
  149. data/lib/mongoid/extensions/boolean.rb +8 -2
  150. data/lib/mongoid/extensions/date.rb +26 -20
  151. data/lib/mongoid/extensions/date_time.rb +1 -1
  152. data/lib/mongoid/extensions/false_class.rb +1 -1
  153. data/lib/mongoid/extensions/float.rb +7 -4
  154. data/lib/mongoid/extensions/hash.rb +37 -8
  155. data/lib/mongoid/extensions/integer.rb +7 -4
  156. data/lib/mongoid/extensions/module.rb +1 -1
  157. data/lib/mongoid/extensions/object.rb +10 -8
  158. data/lib/mongoid/extensions/range.rb +41 -10
  159. data/lib/mongoid/extensions/regexp.rb +11 -4
  160. data/lib/mongoid/extensions/set.rb +11 -4
  161. data/lib/mongoid/extensions/string.rb +11 -22
  162. data/lib/mongoid/extensions/symbol.rb +4 -15
  163. data/lib/mongoid/extensions/time.rb +29 -16
  164. data/lib/mongoid/extensions/time_with_zone.rb +1 -2
  165. data/lib/mongoid/extensions/true_class.rb +1 -1
  166. data/lib/mongoid/extensions.rb +1 -0
  167. data/lib/mongoid/factory.rb +55 -7
  168. data/lib/mongoid/fields/foreign_key.rb +11 -4
  169. data/lib/mongoid/fields/localized.rb +19 -4
  170. data/lib/mongoid/fields/standard.rb +17 -7
  171. data/lib/mongoid/fields/validators/macro.rb +3 -9
  172. data/lib/mongoid/fields.rb +129 -20
  173. data/lib/mongoid/findable.rb +54 -24
  174. data/lib/mongoid/indexable/specification.rb +2 -2
  175. data/lib/mongoid/indexable/validators/options.rb +6 -2
  176. data/lib/mongoid/interceptable.rb +188 -16
  177. data/lib/mongoid/matchable.rb +1 -1
  178. data/lib/mongoid/matcher/eq_impl.rb +1 -1
  179. data/lib/mongoid/matcher/type.rb +1 -1
  180. data/lib/mongoid/matcher.rb +33 -13
  181. data/lib/mongoid/persistable/creatable.rb +19 -9
  182. data/lib/mongoid/persistable/deletable.rb +2 -2
  183. data/lib/mongoid/persistable/destroyable.rb +1 -1
  184. data/lib/mongoid/persistable/savable.rb +14 -2
  185. data/lib/mongoid/persistable/unsettable.rb +2 -2
  186. data/lib/mongoid/persistable/updatable.rb +69 -12
  187. data/lib/mongoid/persistable/upsertable.rb +21 -2
  188. data/lib/mongoid/persistable.rb +6 -3
  189. data/lib/mongoid/persistence_context.rb +6 -4
  190. data/lib/mongoid/query_cache.rb +13 -261
  191. data/lib/mongoid/railties/controller_runtime.rb +1 -1
  192. data/lib/mongoid/railties/database.rake +7 -2
  193. data/lib/mongoid/reloadable.rb +10 -8
  194. data/lib/mongoid/scopable.rb +15 -13
  195. data/lib/mongoid/selectable.rb +1 -2
  196. data/lib/mongoid/serializable.rb +10 -6
  197. data/lib/mongoid/stateful.rb +57 -10
  198. data/lib/mongoid/tasks/database.rake +12 -0
  199. data/lib/mongoid/tasks/database.rb +20 -2
  200. data/lib/mongoid/threaded/lifecycle.rb +5 -5
  201. data/lib/mongoid/threaded.rb +42 -12
  202. data/lib/mongoid/timestamps/created.rb +1 -1
  203. data/lib/mongoid/timestamps/updated.rb +2 -2
  204. data/lib/mongoid/touchable.rb +2 -3
  205. data/lib/mongoid/traversable.rb +5 -4
  206. data/lib/mongoid/utils.rb +22 -0
  207. data/lib/mongoid/validatable/localizable.rb +1 -1
  208. data/lib/mongoid/validatable/macros.rb +5 -7
  209. data/lib/mongoid/validatable/presence.rb +2 -2
  210. data/lib/mongoid/validatable/uniqueness.rb +9 -8
  211. data/lib/mongoid/validatable.rb +9 -6
  212. data/lib/mongoid/version.rb +1 -1
  213. data/lib/mongoid/warnings.rb +19 -4
  214. data/lib/mongoid.rb +17 -3
  215. data/spec/config/mongoid.yml +16 -0
  216. data/spec/integration/app_spec.rb +10 -14
  217. data/spec/integration/associations/belongs_to_spec.rb +18 -0
  218. data/spec/integration/associations/embedded_spec.rb +15 -0
  219. data/spec/integration/associations/embeds_many_spec.rb +15 -2
  220. data/spec/integration/associations/embeds_one_spec.rb +18 -0
  221. data/spec/integration/associations/foreign_key_spec.rb +9 -0
  222. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +21 -0
  223. data/spec/integration/associations/has_one_spec.rb +97 -1
  224. data/spec/integration/associations/scope_option_spec.rb +1 -1
  225. data/spec/integration/callbacks_models.rb +132 -1
  226. data/spec/integration/callbacks_spec.rb +381 -4
  227. data/spec/integration/criteria/range_spec.rb +95 -1
  228. data/spec/integration/discriminator_key_spec.rb +118 -80
  229. data/spec/integration/dots_and_dollars_spec.rb +277 -0
  230. data/spec/integration/i18n_fallbacks_spec.rb +3 -32
  231. data/spec/integration/matcher_examples_spec.rb +20 -13
  232. data/spec/integration/matcher_operator_data/type_decimal.yml +3 -2
  233. data/spec/integration/matcher_operator_spec.rb +3 -5
  234. data/spec/integration/persistence/range_field_spec.rb +350 -0
  235. data/spec/mongoid/association/counter_cache_spec.rb +1 -1
  236. data/spec/mongoid/association/depending_spec.rb +9 -9
  237. data/spec/mongoid/association/eager_spec.rb +2 -1
  238. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +2 -1
  239. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +54 -0
  240. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +96 -9
  241. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +112 -0
  242. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +255 -65
  243. data/spec/mongoid/association/embedded/embeds_many_models.rb +37 -0
  244. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +12 -0
  245. data/spec/mongoid/association/embedded/embeds_many_spec.rb +68 -0
  246. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +25 -0
  247. data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +15 -2
  248. data/spec/mongoid/association/embedded/embeds_one_models.rb +19 -0
  249. data/spec/mongoid/association/embedded/embeds_one_spec.rb +28 -0
  250. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +2 -1
  251. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +54 -0
  252. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +15 -0
  253. data/spec/mongoid/association/referenced/belongs_to_models.rb +11 -0
  254. data/spec/mongoid/association/referenced/belongs_to_spec.rb +4 -20
  255. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +186 -229
  256. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +25 -0
  257. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +35 -2
  258. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +109 -0
  259. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +2 -56
  260. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +173 -177
  261. data/spec/mongoid/association/referenced/has_many_models.rb +3 -1
  262. data/spec/mongoid/association/referenced/has_many_spec.rb +25 -0
  263. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +2 -2
  264. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +107 -1
  265. data/spec/mongoid/association/referenced/has_one_models.rb +16 -0
  266. data/spec/mongoid/association/syncable_spec.rb +15 -1
  267. data/spec/mongoid/atomic/paths_spec.rb +0 -14
  268. data/spec/mongoid/attributes/nested_spec.rb +80 -11
  269. data/spec/mongoid/attributes/nested_spec_models.rb +48 -0
  270. data/spec/mongoid/attributes/projector_spec.rb +1 -5
  271. data/spec/mongoid/attributes_spec.rb +510 -33
  272. data/spec/mongoid/changeable_spec.rb +429 -37
  273. data/spec/mongoid/clients/factory_spec.rb +23 -30
  274. data/spec/mongoid/clients/sessions_spec.rb +0 -38
  275. data/spec/mongoid/clients_spec.rb +149 -15
  276. data/spec/mongoid/collection_configurable_spec.rb +158 -0
  277. data/spec/mongoid/config/defaults_spec.rb +160 -0
  278. data/spec/mongoid/config_spec.rb +214 -31
  279. data/spec/mongoid/contextual/aggregable/memory_spec.rb +396 -158
  280. data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
  281. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
  282. data/spec/mongoid/contextual/map_reduce_spec.rb +2 -16
  283. data/spec/mongoid/contextual/memory_spec.rb +850 -88
  284. data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +187 -0
  285. data/spec/mongoid/contextual/mongo_spec.rb +2309 -1127
  286. data/spec/mongoid/contextual/none_spec.rb +60 -21
  287. data/spec/mongoid/copyable_spec.rb +453 -11
  288. data/spec/mongoid/criteria/findable_spec.rb +86 -210
  289. data/spec/mongoid/criteria/includable_spec.rb +1492 -0
  290. data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
  291. data/spec/mongoid/criteria/marshalable_spec.rb +18 -1
  292. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +7 -19
  293. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +134 -26
  294. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +11 -0
  295. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +11 -0
  296. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +0 -15
  297. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +73 -7
  298. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +4 -69
  299. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +0 -59
  300. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +11 -0
  301. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +11 -0
  302. data/spec/mongoid/criteria/queryable/optional_spec.rb +15 -484
  303. data/spec/mongoid/criteria/queryable/options_spec.rb +1 -1
  304. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +469 -0
  305. data/spec/mongoid/criteria/queryable/selectable_spec.rb +78 -86
  306. data/spec/mongoid/criteria/queryable/selector_spec.rb +15 -3
  307. data/spec/mongoid/criteria/translator_spec.rb +132 -0
  308. data/spec/mongoid/criteria_projection_spec.rb +1 -5
  309. data/spec/mongoid/criteria_spec.rb +469 -1205
  310. data/spec/mongoid/document_fields_spec.rb +173 -24
  311. data/spec/mongoid/document_spec.rb +32 -41
  312. data/spec/mongoid/errors/document_not_found_spec.rb +29 -2
  313. data/spec/mongoid/errors/invalid_field_spec.rb +1 -1
  314. data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
  315. data/spec/mongoid/errors/mongoid_error_spec.rb +3 -1
  316. data/spec/mongoid/errors/no_environment_spec.rb +3 -3
  317. data/spec/mongoid/errors/readonly_document_spec.rb +2 -2
  318. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +1 -1
  319. data/spec/mongoid/extensions/array_spec.rb +16 -2
  320. data/spec/mongoid/extensions/big_decimal_spec.rb +712 -212
  321. data/spec/mongoid/extensions/binary_spec.rb +44 -9
  322. data/spec/mongoid/extensions/boolean_spec.rb +68 -82
  323. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +7 -3
  324. data/spec/mongoid/extensions/date_spec.rb +71 -1
  325. data/spec/mongoid/extensions/date_time_spec.rb +15 -9
  326. data/spec/mongoid/extensions/float_spec.rb +53 -74
  327. data/spec/mongoid/extensions/hash_spec.rb +33 -3
  328. data/spec/mongoid/extensions/integer_spec.rb +50 -64
  329. data/spec/mongoid/extensions/range_spec.rb +255 -54
  330. data/spec/mongoid/extensions/regexp_spec.rb +58 -33
  331. data/spec/mongoid/extensions/set_spec.rb +106 -0
  332. data/spec/mongoid/extensions/string_spec.rb +53 -25
  333. data/spec/mongoid/extensions/symbol_spec.rb +18 -25
  334. data/spec/mongoid/extensions/time_spec.rb +639 -106
  335. data/spec/mongoid/extensions/time_with_zone_spec.rb +24 -83
  336. data/spec/mongoid/factory_spec.rb +61 -1
  337. data/spec/mongoid/fields/localized_spec.rb +80 -37
  338. data/spec/mongoid/fields_spec.rb +500 -84
  339. data/spec/mongoid/findable_spec.rb +450 -58
  340. data/spec/mongoid/indexable/specification_spec.rb +2 -2
  341. data/spec/mongoid/indexable_spec.rb +55 -30
  342. data/spec/mongoid/interceptable_spec.rb +824 -22
  343. data/spec/mongoid/interceptable_spec_models.rb +235 -4
  344. data/spec/mongoid/matcher/extract_attribute_spec.rb +1 -5
  345. data/spec/mongoid/mongoizable_spec.rb +285 -0
  346. data/spec/mongoid/persistable/creatable_spec.rb +2 -2
  347. data/spec/mongoid/persistable/deletable_spec.rb +28 -8
  348. data/spec/mongoid/persistable/destroyable_spec.rb +28 -8
  349. data/spec/mongoid/persistable/incrementable_spec.rb +37 -0
  350. data/spec/mongoid/persistable/logical_spec.rb +37 -0
  351. data/spec/mongoid/persistable/poppable_spec.rb +36 -0
  352. data/spec/mongoid/persistable/pullable_spec.rb +72 -0
  353. data/spec/mongoid/persistable/pushable_spec.rb +72 -0
  354. data/spec/mongoid/persistable/renamable_spec.rb +36 -0
  355. data/spec/mongoid/persistable/savable_spec.rb +96 -0
  356. data/spec/mongoid/persistable/settable_spec.rb +37 -0
  357. data/spec/mongoid/persistable/unsettable_spec.rb +36 -0
  358. data/spec/mongoid/persistable/updatable_spec.rb +20 -28
  359. data/spec/mongoid/persistable/upsertable_spec.rb +89 -1
  360. data/spec/mongoid/persistence_context_spec.rb +31 -57
  361. data/spec/mongoid/query_cache_middleware_spec.rb +0 -18
  362. data/spec/mongoid/query_cache_spec.rb +56 -215
  363. data/spec/mongoid/reloadable_spec.rb +83 -6
  364. data/spec/mongoid/scopable_spec.rb +91 -1
  365. data/spec/mongoid/serializable_spec.rb +9 -30
  366. data/spec/mongoid/shardable_spec.rb +4 -4
  367. data/spec/mongoid/stateful_spec.rb +150 -8
  368. data/spec/mongoid/tasks/database_rake_spec.rb +74 -0
  369. data/spec/mongoid/tasks/database_spec.rb +127 -0
  370. data/spec/mongoid/timestamps_spec.rb +392 -4
  371. data/spec/mongoid/timestamps_spec_models.rb +67 -0
  372. data/spec/mongoid/touchable_spec.rb +390 -2
  373. data/spec/mongoid/touchable_spec_models.rb +14 -8
  374. data/spec/mongoid/traversable_spec.rb +13 -35
  375. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  376. data/spec/mongoid/validatable/uniqueness_spec.rb +58 -31
  377. data/spec/mongoid/warnings_spec.rb +35 -0
  378. data/spec/mongoid_spec.rb +34 -16
  379. data/spec/rails/controller_extension/controller_runtime_spec.rb +2 -2
  380. data/spec/rails/mongoid_spec.rb +4 -16
  381. data/spec/shared/lib/mrss/docker_runner.rb +8 -0
  382. data/spec/shared/lib/mrss/lite_constraints.rb +2 -2
  383. data/spec/shared/lib/mrss/server_version_registry.rb +16 -23
  384. data/spec/shared/lib/mrss/utils.rb +28 -6
  385. data/spec/shared/share/Dockerfile.erb +36 -40
  386. data/spec/shared/shlib/server.sh +28 -4
  387. data/spec/shared/shlib/set_env.sh +4 -4
  388. data/spec/spec_helper.rb +5 -0
  389. data/spec/support/constraints.rb +24 -0
  390. data/spec/support/immutable_ids.rb +118 -0
  391. data/spec/support/macros.rb +78 -0
  392. data/spec/support/models/artist.rb +0 -1
  393. data/spec/support/models/augmentation.rb +12 -0
  394. data/spec/support/models/band.rb +4 -0
  395. data/spec/support/models/book.rb +1 -0
  396. data/spec/support/models/building.rb +2 -0
  397. data/spec/support/models/catalog.rb +24 -0
  398. data/spec/support/models/circus.rb +3 -0
  399. data/spec/support/models/cover.rb +10 -0
  400. data/spec/support/models/fanatic.rb +8 -0
  401. data/spec/support/models/implant.rb +9 -0
  402. data/spec/support/models/label.rb +2 -0
  403. data/spec/support/models/passport.rb +9 -0
  404. data/spec/support/models/person.rb +2 -0
  405. data/spec/support/models/player.rb +2 -0
  406. data/spec/support/models/powerup.rb +12 -0
  407. data/spec/support/models/product.rb +1 -0
  408. data/spec/support/models/purse.rb +9 -0
  409. data/spec/support/models/registry.rb +1 -0
  410. data/spec/support/models/school.rb +14 -0
  411. data/spec/support/models/shield.rb +18 -0
  412. data/spec/support/models/student.rb +14 -0
  413. data/spec/support/models/weapon.rb +12 -0
  414. data.tar.gz.sig +0 -0
  415. metadata +100 -22
  416. metadata.gz.sig +0 -0
  417. data/lib/mongoid/errors/eager_load.rb +0 -23
  418. data/lib/mongoid/errors/invalid_value.rb +0 -17
  419. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +0 -60
  420. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +0 -60
  421. data/spec/mongoid/errors/eager_load_spec.rb +0 -31
@@ -1862,51 +1862,56 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
1862
1862
  end
1863
1863
  end
1864
1864
 
1865
- describe "#delete" do
1865
+ %i[ delete delete_one ].each do |method|
1866
+ describe "\##{method}" do
1867
+ let(:address_one) { Address.new(street: "first") }
1868
+ let(:address_two) { Address.new(street: "second") }
1866
1869
 
1867
- let(:person) do
1868
- Person.new
1869
- end
1870
-
1871
- let(:address_one) do
1872
- Address.new(street: "first")
1873
- end
1870
+ before do
1871
+ person.addresses << [ address_one, address_two ]
1872
+ end
1874
1873
 
1875
- let(:address_two) do
1876
- Address.new(street: "second")
1877
- end
1874
+ shared_examples_for 'deleting from the collection' do
1875
+ context 'when the document exists in the relation' do
1876
+ let!(:deleted) do
1877
+ person.addresses.send(method, address_one)
1878
+ end
1878
1879
 
1879
- before do
1880
- person.addresses << [ address_one, address_two ]
1881
- end
1880
+ it 'deletes the document' do
1881
+ expect(person.addresses).to eq([ address_two ])
1882
+ expect(person.reload.addresses).to eq([ address_two ]) if person.persisted?
1883
+ end
1882
1884
 
1883
- context "when the document exists in the relation" do
1885
+ it 'deletes the document from the unscoped' do
1886
+ expect(person.addresses.send(:_unscoped)).to eq([ address_two ])
1887
+ end
1884
1888
 
1885
- let!(:deleted) do
1886
- person.addresses.delete(address_one)
1887
- end
1889
+ it 'reindexes the relation' do
1890
+ expect(address_two._index).to eq(0)
1891
+ end
1888
1892
 
1889
- it "deletes the document" do
1890
- expect(person.addresses).to eq([ address_two ])
1891
- end
1893
+ it 'returns the document' do
1894
+ expect(deleted).to eq(address_one)
1895
+ end
1896
+ end
1892
1897
 
1893
- it "deletes the document from the unscoped" do
1894
- expect(person.addresses.send(:_unscoped)).to eq([ address_two ])
1898
+ context 'when the document does not exist' do
1899
+ it 'returns nil' do
1900
+ expect(person.addresses.send(method, Address.new)).to be_nil
1901
+ end
1902
+ end
1895
1903
  end
1896
1904
 
1897
- it "reindexes the relation" do
1898
- expect(address_two._index).to eq(0)
1899
- end
1905
+ context 'when the root document is unpersisted' do
1906
+ let(:person) { Person.new }
1900
1907
 
1901
- it "returns the document" do
1902
- expect(deleted).to eq(address_one)
1908
+ it_behaves_like 'deleting from the collection'
1903
1909
  end
1904
- end
1905
1910
 
1906
- context "when the document does not exist" do
1911
+ context 'when the root document is persisted' do
1912
+ let(:person) { Person.create }
1907
1913
 
1908
- it "returns nil" do
1909
- expect(person.addresses.delete(Address.new)).to be_nil
1914
+ it_behaves_like 'deleting from the collection'
1910
1915
  end
1911
1916
  end
1912
1917
  end
@@ -2210,6 +2215,79 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
2210
2215
  end
2211
2216
  end
2212
2217
  end
2218
+
2219
+ context "when modifying the document beforehand" do
2220
+ let(:parent) { EmmParent.new }
2221
+
2222
+ before do
2223
+
2224
+ parent.blocks << EmmBlock.new(name: 'test', children: [size: 1, order: 1])
2225
+ parent.save!
2226
+
2227
+ parent.blocks[0].children[0].assign_attributes(size: 2)
2228
+
2229
+ parent.blocks.destroy_all(:name => 'test')
2230
+ end
2231
+
2232
+ it "deletes the correct document in the database" do
2233
+ expect(parent.reload.blocks.length).to eq(0)
2234
+ end
2235
+ end
2236
+
2237
+ context "when nil _id" do
2238
+ let(:parent) { EmmParent.new }
2239
+
2240
+ before do
2241
+ parent.blocks << EmmBlock.new(_id: nil, name: 'test', children: [size: 1, order: 1])
2242
+ parent.blocks << EmmBlock.new(_id: nil, name: 'test2', children: [size: 1, order: 1])
2243
+ parent.save!
2244
+
2245
+ parent.blocks.destroy_all(:name => 'test')
2246
+ end
2247
+
2248
+ it "deletes only the matching documents in the database" do
2249
+ expect(parent.reload.blocks.length).to eq(1)
2250
+ end
2251
+ end
2252
+
2253
+ # Since without an _id field we must us a $pullAll with the attributes of
2254
+ # the embedded document, if you modify it beforehand, the query will not
2255
+ # be able to find the correct document to pull.
2256
+ context "when modifying the document with nil _id" do
2257
+ let(:parent) { EmmParent.new }
2258
+
2259
+ before do
2260
+ parent.blocks << EmmBlock.new(_id: nil, name: 'test', children: [size: 1, order: 1])
2261
+ parent.blocks << EmmBlock.new(_id: nil, name: 'test2', children: [size: 1, order: 1])
2262
+ parent.save!
2263
+
2264
+ parent.blocks[0].children[0].assign_attributes(size: 2)
2265
+
2266
+ parent.blocks.destroy_all(:name => 'test')
2267
+ end
2268
+
2269
+ it "does not delete the correct documents" do
2270
+ expect(parent.reload.blocks.length).to eq(2)
2271
+ end
2272
+ end
2273
+
2274
+ context "when documents with and without _id" do
2275
+ let(:parent) { EmmParent.new }
2276
+
2277
+ before do
2278
+ parent.blocks << EmmBlock.new(_id: nil, name: 'test', children: [size: 1, order: 1])
2279
+ parent.blocks << EmmBlock.new(name: 'test', children: [size: 1, order: 1])
2280
+ parent.save!
2281
+
2282
+ parent.blocks[1].children[0].assign_attributes(size: 2)
2283
+
2284
+ parent.blocks.destroy_all(:name => 'test')
2285
+ end
2286
+
2287
+ it "does not delete the correct documents" do
2288
+ expect(parent.reload.blocks.length).to eq(0)
2289
+ end
2290
+ end
2213
2291
  end
2214
2292
  end
2215
2293
 
@@ -2279,32 +2357,22 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
2279
2357
  context "when the id does not match" do
2280
2358
 
2281
2359
  context "when config set to raise error" do
2282
-
2283
- before do
2284
- Mongoid.raise_not_found_error = true
2285
- end
2360
+ config_override :raise_not_found_error, true
2286
2361
 
2287
2362
  it "raises an error" do
2288
2363
  expect {
2289
2364
  person.addresses.find(BSON::ObjectId.new)
2290
- }.to raise_error(Mongoid::Errors::DocumentNotFound)
2365
+ }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Address with id\(s\)/)
2291
2366
  end
2292
2367
  end
2293
2368
 
2294
2369
  context "when config set not to raise error" do
2370
+ config_override :raise_not_found_error, false
2295
2371
 
2296
2372
  let(:address) do
2297
2373
  person.addresses.find(BSON::ObjectId.new)
2298
2374
  end
2299
2375
 
2300
- before do
2301
- Mongoid.raise_not_found_error = false
2302
- end
2303
-
2304
- after do
2305
- Mongoid.raise_not_found_error = true
2306
- end
2307
-
2308
2376
  it "returns nil" do
2309
2377
  expect(address).to be_nil
2310
2378
  end
@@ -2328,32 +2396,22 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
2328
2396
  context "when the ids do not match" do
2329
2397
 
2330
2398
  context "when config set to raise error" do
2331
-
2332
- before do
2333
- Mongoid.raise_not_found_error = true
2334
- end
2399
+ config_override :raise_not_found_error, true
2335
2400
 
2336
2401
  it "raises an error" do
2337
2402
  expect {
2338
2403
  person.addresses.find([ BSON::ObjectId.new ])
2339
- }.to raise_error(Mongoid::Errors::DocumentNotFound)
2404
+ }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Address with id\(s\)/)
2340
2405
  end
2341
2406
  end
2342
2407
 
2343
2408
  context "when config set not to raise error" do
2409
+ config_override :raise_not_found_error, false
2344
2410
 
2345
2411
  let(:addresses) do
2346
2412
  person.addresses.find([ BSON::ObjectId.new ])
2347
2413
  end
2348
2414
 
2349
- before do
2350
- Mongoid.raise_not_found_error = false
2351
- end
2352
-
2353
- after do
2354
- Mongoid.raise_not_found_error = true
2355
- end
2356
-
2357
2415
  it "returns an empty array" do
2358
2416
  expect(addresses).to be_empty
2359
2417
  end
@@ -3461,7 +3519,7 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
3461
3519
 
3462
3520
  describe "replacing the entire embedded list" do
3463
3521
 
3464
- context "when an embeds many relationship contains a nil as the first item" do
3522
+ context "when an embeds many relationship contains nil as the first item" do
3465
3523
 
3466
3524
  let(:person) do
3467
3525
  Person.create!
@@ -3482,7 +3540,7 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
3482
3540
  end
3483
3541
  end
3484
3542
 
3485
- context "when an embeds many relationship contains a nil in the middle of the list" do
3543
+ context "when an embeds many relationship contains nil in the middle of the list" do
3486
3544
 
3487
3545
  let(:person) do
3488
3546
  Person.create!
@@ -3503,7 +3561,7 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
3503
3561
  end
3504
3562
  end
3505
3563
 
3506
- context "when an embeds many relationship contains a nil at the end of the list" do
3564
+ context "when an embeds many relationship contains nil at the end of the list" do
3507
3565
 
3508
3566
  let(:person) do
3509
3567
  Person.create!
@@ -3527,7 +3585,7 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
3527
3585
 
3528
3586
  describe "appending to the embedded list" do
3529
3587
 
3530
- context "when appending a nil to the first position in an embedded list" do
3588
+ context "when appending nil to the first position in an embedded list" do
3531
3589
 
3532
3590
  let(:person) do
3533
3591
  Person.create! phone_numbers: []
@@ -3546,7 +3604,7 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
3546
3604
  end
3547
3605
  end
3548
3606
 
3549
- context "when appending a nil into the middle of an embedded list" do
3607
+ context "when appending nil into the middle of an embedded list" do
3550
3608
 
3551
3609
  let(:person) do
3552
3610
  Person.create! phone_numbers: []
@@ -3565,7 +3623,7 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
3565
3623
  end
3566
3624
  end
3567
3625
 
3568
- context "when appending a nil to the end of an embedded list" do
3626
+ context "when appending nil to the end of an embedded list" do
3569
3627
 
3570
3628
  let(:person) do
3571
3629
  Person.create! phone_numbers: []
@@ -3960,6 +4018,28 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
3960
4018
  end
3961
4019
  end
3962
4020
 
4021
+ context "when destroying a document with multiple nil _ids" do
4022
+ let(:congress) { EmmCongress.create! }
4023
+
4024
+ before do
4025
+ congress.legislators << EmmLegislator.new(_id: nil, a: 1)
4026
+ congress.legislators << EmmLegislator.new(_id: nil, a: 2)
4027
+
4028
+ congress.legislators[0].destroy
4029
+ end
4030
+
4031
+ it "deletes the correct document locally" do
4032
+ pending "MONGOID-5394"
4033
+ expect(congress.legislators.length).to eq(1)
4034
+ expect(congress.legislators.first.a).to eq(1)
4035
+ end
4036
+
4037
+ it "only deletes the one document" do
4038
+ pending "MONGOID-5394"
4039
+ expect(congress.reload.legislators.length).to eq(1)
4040
+ end
4041
+ end
4042
+
3963
4043
  context "when adding a document" do
3964
4044
 
3965
4045
  let(:person) do
@@ -4491,7 +4571,7 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
4491
4571
  before do
4492
4572
  band.collection.
4493
4573
  find(_id: band.id).
4494
- update_one("$set" => { records: [{ name: "Moderat" }]})
4574
+ update_one("$set" => { records: [{ _id: BSON::ObjectId.new, name: "Moderat" }]})
4495
4575
  end
4496
4576
 
4497
4577
  context "when loading the documents" do
@@ -4651,6 +4731,55 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
4651
4731
  end
4652
4732
  end
4653
4733
 
4734
+ context "when trying to persist the empty list" do
4735
+
4736
+ context "in an embeds_many relation" do
4737
+
4738
+ let(:band) { Band.create! }
4739
+
4740
+ before do
4741
+ band.labels = []
4742
+ band.save!
4743
+ end
4744
+
4745
+ let(:reloaded_band) { Band.collection.find(_id: band._id).first }
4746
+
4747
+ it "persists the empty list" do
4748
+ expect(reloaded_band).to have_key(:labels)
4749
+ expect(reloaded_band[:labels]).to eq []
4750
+ end
4751
+ end
4752
+
4753
+ context "in a nested embeds_many relation" do
4754
+
4755
+ let(:survey) { Survey.create!(questions: [Question.new]) }
4756
+
4757
+ before do
4758
+ survey.questions.first.answers = []
4759
+ survey.save!
4760
+ end
4761
+
4762
+ let(:reloaded_survey) { Survey.collection.find(_id: survey._id).first }
4763
+
4764
+ it "persists the empty list" do
4765
+ expect(reloaded_survey).to have_key(:questions)
4766
+ expect(reloaded_survey[:questions][0]).to have_key(:answers)
4767
+ expect(reloaded_survey[:questions][0][:answers]).to eq []
4768
+ end
4769
+ end
4770
+
4771
+ context "when not setting the embeds_many field" do
4772
+
4773
+ let(:band) { Band.create! }
4774
+
4775
+ let(:reloaded_band) { Band.collection.find(_id: band._id).first }
4776
+
4777
+ it "does not persist the empty list" do
4778
+ expect(reloaded_band).to_not have_key(:labels)
4779
+ end
4780
+ end
4781
+ end
4782
+
4654
4783
  context "when using assign_attributes with an already populated array" do
4655
4784
  let(:post) { EmmPost.create! }
4656
4785
 
@@ -4670,4 +4799,65 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
4670
4799
  expect(post.company_tags.first.title).to eq("c")
4671
4800
  end
4672
4801
  end
4802
+
4803
+ context "when the parent fails validation" do
4804
+ let(:school) { EmmSchool.new }
4805
+ let(:student) { school.students.new }
4806
+
4807
+ before do
4808
+ student.save
4809
+ end
4810
+
4811
+ it "does not mark the parent as persisted" do
4812
+ expect(school.persisted?).to be false
4813
+ end
4814
+
4815
+ it "does not mark the child as persisted" do
4816
+ expect(student.persisted?).to be false
4817
+ end
4818
+
4819
+ it "does not persist the parent" do
4820
+ expect(School.count).to eq(0)
4821
+ end
4822
+ end
4823
+
4824
+ context "when doing assign_attributes then assignment" do
4825
+
4826
+ let(:post) do
4827
+ EmmPost.create!(
4828
+ company_tags: [ EmmCompanyTag.new(title: "1"), EmmCompanyTag.new(title: "1") ],
4829
+ user_tags: [ EmmUserTag.new(title: "1"), EmmUserTag.new(title: "1") ]
4830
+ )
4831
+ end
4832
+
4833
+ let(:from_db) { EmmPost.find(post.id) }
4834
+
4835
+ before do
4836
+ post.assign_attributes(
4837
+ company_tags: [ EmmCompanyTag.new(title: '3'), EmmCompanyTag.new(title: '4') ]
4838
+ )
4839
+ post.user_tags = [ EmmUserTag.new(title: '3'), EmmUserTag.new(title: '4') ]
4840
+ post.save!
4841
+ end
4842
+
4843
+ it "persists the associations correctly" do
4844
+ expect(from_db.user_tags.size).to eq(2)
4845
+ expect(from_db.company_tags.size).to eq(2)
4846
+ end
4847
+ end
4848
+
4849
+ context "when assigning hashes" do
4850
+ let(:user) { EmmUser.create! }
4851
+
4852
+ before do
4853
+ user.orders = [ { sku: 1 }, { sku: 2 } ]
4854
+ end
4855
+
4856
+ it "creates the objects correctly" do
4857
+ expect(user.orders.first).to be_a(EmmOrder)
4858
+ expect(user.orders.last).to be_a(EmmOrder)
4859
+
4860
+ expect(user.orders.map(&:sku).sort).to eq([ 1, 2 ])
4861
+ end
4862
+ end
4673
4863
  end
@@ -100,6 +100,7 @@ end
100
100
  class EmmOrder
101
101
  include Mongoid::Document
102
102
 
103
+ field :sku
103
104
  field :amount, type: Integer
104
105
 
105
106
  embedded_in :user, class_name: 'EmmUser'
@@ -188,3 +189,39 @@ class EmmUserTag
188
189
  embedded_in :post, class_name: "EmmPost"
189
190
  end
190
191
 
192
+ class EmmSchool
193
+ include Mongoid::Document
194
+
195
+ embeds_many :students, class_name: "EmmStudent"
196
+
197
+ field :name, type: :string
198
+
199
+ validates :name, presence: true
200
+ end
201
+
202
+ class EmmStudent
203
+ include Mongoid::Document
204
+
205
+ embedded_in :school, class_name: "EmmSchool"
206
+ end
207
+
208
+ class EmmParent
209
+ include Mongoid::Document
210
+ embeds_many :blocks, class_name: "EmmBlock"
211
+ end
212
+
213
+ class EmmBlock
214
+ include Mongoid::Document
215
+ field :name, type: String
216
+ embeds_many :children, class_name: "EmmChild"
217
+ end
218
+
219
+ class EmmChild
220
+ include Mongoid::Document
221
+ embedded_in :block, class_name: "EmmBlock"
222
+
223
+ field :size, type: Integer
224
+ field :order, type: Integer
225
+ field :t
226
+ end
227
+
@@ -47,5 +47,17 @@ describe Mongoid::Association::Embedded::EmbedsMany do
47
47
  expect(patient.addresses.first.number).to eq(123)
48
48
  end
49
49
  end
50
+
51
+ context "when excluding the relation" do
52
+ let(:congress) do
53
+ EmmCongress.where(name: 'foo').only(:_id).first
54
+ end
55
+
56
+ it 'raises a MissingAttributeError' do
57
+ expect do
58
+ congress.legislators
59
+ end.to raise_error(ActiveModel::MissingAttributeError)
60
+ end
61
+ end
50
62
  end
51
63
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "spec_helper"
4
+ require_relative 'embeds_many_models'
4
5
 
5
6
  describe Mongoid::Association::Embedded::EmbedsMany do
6
7
 
@@ -861,4 +862,71 @@ describe Mongoid::Association::Embedded::EmbedsMany do
861
862
  expect(association.path(double( :_parent => true))).to be_a(Mongoid::Atomic::Paths::Embedded::Many)
862
863
  end
863
864
  end
865
+
866
+ context "when the document and embedded document's klass is in a submodule" do
867
+
868
+ let(:tank) { EmmSpec::Tank.create! }
869
+ let(:gun) { tank.guns.create! }
870
+
871
+ let(:inverse_assoc) { gun._association.inverse_association }
872
+
873
+ it "has the correct inverses" do
874
+ pending 'MONGOID-5080'
875
+
876
+ inverse_assoc.should be_a(Mongoid::Association::Embedded::EmbeddedIn)
877
+ inverse_assoc.name.should == :tank
878
+ end
879
+
880
+ context "when embedded association is not namespaced but has class_name" do
881
+
882
+ let(:turret) { tank.emm_turrets.create! }
883
+
884
+ let(:inverse_assoc) { turret._association.inverse_association }
885
+
886
+ it "has the correct inverses" do
887
+ inverse_assoc.should be_a(Mongoid::Association::Embedded::EmbeddedIn)
888
+ inverse_assoc.name.should == :tank
889
+ end
890
+ end
891
+
892
+ context "when embedded association is not namespaced and lacks class_name" do
893
+
894
+ let(:hatch) { tank.emm_hatches.create! }
895
+
896
+ let(:inverse_assoc) { hatch._association.inverse_association }
897
+
898
+ it "does not find the inverse" do
899
+ inverse_assoc.should be nil
900
+ end
901
+ end
902
+
903
+ context "when the class names exist on top level and namespaced" do
904
+
905
+ let(:car) { EmmSpec::Car.create! }
906
+ let(:door) { car.doors.create! }
907
+
908
+ let(:inverse_assoc) { door._association.inverse_association }
909
+
910
+ it "has the correct inverses" do
911
+ pending 'MONGOID-5080'
912
+
913
+ inverse_assoc.should be_a(Mongoid::Association::Embedded::EmbeddedIn)
914
+ inverse_assoc.name.should == :car
915
+ end
916
+ end
917
+
918
+ context "when the association has an unqualified class_name in same module" do
919
+
920
+ let(:launcher) { tank.launchers.create! }
921
+
922
+ let(:inverse_assoc) { launcher._association.inverse_association }
923
+
924
+ it "has the correct inverses" do
925
+ pending 'unqualified class_name arguments do not work per MONGOID-5080'
926
+
927
+ inverse_assoc.should be_a(Mongoid::Association::Embedded::EmbeddedIn)
928
+ inverse_assoc.name.should == :tank
929
+ end
930
+ end
931
+ end
864
932
  end
@@ -78,4 +78,29 @@ describe Mongoid::Association::Embedded::EmbedsOne::Buildable do
78
78
  end
79
79
  end
80
80
  end
81
+
82
+ context 'when the object is already associated with another object' do
83
+
84
+ let(:owner1) do
85
+ Owner.create!
86
+ end
87
+
88
+ let(:owner2) do
89
+ Owner.create!
90
+ end
91
+
92
+ let(:scribe) do
93
+ Scribe.new
94
+ end
95
+
96
+ before do
97
+ owner1.scribe = scribe
98
+ owner2.scribe = scribe
99
+ end
100
+
101
+ it 'clears the object of its previous association' do
102
+ expect(owner1.scribe).to be_nil
103
+ expect(owner2.scribe).to eq(scribe)
104
+ end
105
+ end
81
106
  end
@@ -202,7 +202,7 @@ describe Mongoid::Association::Embedded::EmbedsOne::Proxy do
202
202
  end
203
203
  end
204
204
  end
205
-
205
+
206
206
  context 'when the original document does not need to be unset because it will be replaced by the $set' do
207
207
 
208
208
  let!(:pet_owner) do
@@ -971,7 +971,7 @@ describe Mongoid::Association::Embedded::EmbedsOne::Proxy do
971
971
  before do
972
972
  band.collection.
973
973
  find(_id: band.id).
974
- update_one("$set" => { label: { name: "Mute" }})
974
+ update_one("$set" => { label: { _id: BSON::ObjectId.new, name: "Mute" }})
975
975
  end
976
976
 
977
977
  context "when loading the documents" do
@@ -1022,4 +1022,17 @@ describe Mongoid::Association::Embedded::EmbedsOne::Proxy do
1022
1022
  expect(building.building_address).to be_a(BuildingAddress)
1023
1023
  end
1024
1024
  end
1025
+
1026
+ context "when assigning a hash" do
1027
+ let(:building) { Building.create! }
1028
+
1029
+ before do
1030
+ building.building_address = { city: "NYC" }
1031
+ end
1032
+
1033
+ it "creates the objects correctly" do
1034
+ expect(building.building_address).to be_a(BuildingAddress)
1035
+ expect(building.building_address.city).to eq("NYC")
1036
+ end
1037
+ end
1025
1038
  end
@@ -52,3 +52,22 @@ class EomDnlChild
52
52
  embedded_in :parent, class_name: 'EomDnlParent'
53
53
  embedded_in :missing_parent, class_name: 'EomDnlMissingParent'
54
54
  end
55
+
56
+ class EomAddress
57
+ include Mongoid::Document
58
+
59
+ field :city, type: String
60
+
61
+ embedded_in :addressable, polymorphic: true
62
+ end
63
+
64
+ # app/models/company.rb
65
+ class EomCompany
66
+ include Mongoid::Document
67
+
68
+ embeds_one :address, class_name: 'EomAddress', as: :addressable
69
+ accepts_nested_attributes_for :address
70
+
71
+ embeds_one :delivery_address, class_name: 'EomAddress', as: :addressable
72
+ accepts_nested_attributes_for :delivery_address
73
+ end