mongoid 7.5.1 → 8.1.2

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 (424) 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/Rakefile +25 -0
  6. data/lib/config/locales/en.yml +92 -43
  7. data/lib/mongoid/association/accessors.rb +40 -11
  8. data/lib/mongoid/association/bindable.rb +50 -2
  9. data/lib/mongoid/association/builders.rb +5 -3
  10. data/lib/mongoid/association/constrainable.rb +0 -1
  11. data/lib/mongoid/association/eager_loadable.rb +29 -7
  12. data/lib/mongoid/association/embedded/batchable.rb +54 -14
  13. data/lib/mongoid/association/embedded/cyclic.rb +1 -1
  14. data/lib/mongoid/association/embedded/embedded_in/binding.rb +24 -2
  15. data/lib/mongoid/association/embedded/embedded_in/buildable.rb +2 -2
  16. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +4 -3
  17. data/lib/mongoid/association/embedded/embedded_in.rb +3 -2
  18. data/lib/mongoid/association/embedded/embeds_many/binding.rb +1 -0
  19. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +4 -3
  20. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +69 -45
  21. data/lib/mongoid/association/embedded/embeds_many.rb +2 -2
  22. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +19 -5
  23. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +24 -5
  24. data/lib/mongoid/association/embedded/embeds_one.rb +3 -3
  25. data/lib/mongoid/association/macros.rb +8 -1
  26. data/lib/mongoid/association/many.rb +11 -7
  27. data/lib/mongoid/association/nested/many.rb +5 -4
  28. data/lib/mongoid/association/nested/nested_buildable.rb +4 -4
  29. data/lib/mongoid/association/nested/one.rb +45 -7
  30. data/lib/mongoid/association/one.rb +2 -2
  31. data/lib/mongoid/association/options.rb +9 -9
  32. data/lib/mongoid/association/proxy.rb +15 -4
  33. data/lib/mongoid/association/referenced/auto_save.rb +4 -3
  34. data/lib/mongoid/association/referenced/belongs_to/binding.rb +1 -0
  35. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +1 -1
  36. data/lib/mongoid/association/referenced/belongs_to/proxy.rb +5 -6
  37. data/lib/mongoid/association/referenced/belongs_to.rb +2 -2
  38. data/lib/mongoid/association/referenced/counter_cache.rb +10 -10
  39. data/lib/mongoid/association/referenced/eager.rb +2 -2
  40. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +70 -13
  41. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +6 -3
  42. data/lib/mongoid/association/referenced/has_many/enumerable.rb +22 -30
  43. data/lib/mongoid/association/referenced/has_many/proxy.rb +29 -19
  44. data/lib/mongoid/association/referenced/has_many.rb +3 -3
  45. data/lib/mongoid/association/referenced/has_one/buildable.rb +1 -1
  46. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +5 -5
  47. data/lib/mongoid/association/referenced/has_one/proxy.rb +9 -12
  48. data/lib/mongoid/association/referenced/has_one.rb +3 -3
  49. data/lib/mongoid/association/referenced/syncable.rb +4 -4
  50. data/lib/mongoid/association/reflections.rb +4 -4
  51. data/lib/mongoid/association/relatable.rb +44 -10
  52. data/lib/mongoid/association.rb +5 -5
  53. data/lib/mongoid/atomic/modifiers.rb +2 -2
  54. data/lib/mongoid/atomic/paths/embedded/many.rb +19 -0
  55. data/lib/mongoid/atomic.rb +7 -0
  56. data/lib/mongoid/attributes/dynamic.rb +4 -4
  57. data/lib/mongoid/attributes/nested.rb +6 -6
  58. data/lib/mongoid/attributes/processing.rb +37 -6
  59. data/lib/mongoid/attributes/projector.rb +2 -2
  60. data/lib/mongoid/attributes/readonly.rb +3 -3
  61. data/lib/mongoid/attributes.rb +51 -42
  62. data/lib/mongoid/cacheable.rb +2 -2
  63. data/lib/mongoid/changeable.rb +147 -14
  64. data/lib/mongoid/clients/options.rb +5 -1
  65. data/lib/mongoid/clients/sessions.rb +2 -14
  66. data/lib/mongoid/clients/storage_options.rb +2 -5
  67. data/lib/mongoid/clients/validators/storage.rb +3 -15
  68. data/lib/mongoid/collection_configurable.rb +58 -0
  69. data/lib/mongoid/composable.rb +2 -0
  70. data/lib/mongoid/config/defaults.rb +60 -0
  71. data/lib/mongoid/config/options.rb +3 -0
  72. data/lib/mongoid/config/validators/async_query_executor.rb +24 -0
  73. data/lib/mongoid/config/validators/client.rb +6 -6
  74. data/lib/mongoid/config/validators.rb +1 -0
  75. data/lib/mongoid/config.rb +145 -17
  76. data/lib/mongoid/contextual/aggregable/memory.rb +24 -16
  77. data/lib/mongoid/contextual/aggregable/mongo.rb +5 -5
  78. data/lib/mongoid/contextual/aggregable/none.rb +1 -1
  79. data/lib/mongoid/contextual/atomic.rb +1 -1
  80. data/lib/mongoid/contextual/geo_near.rb +7 -7
  81. data/lib/mongoid/contextual/map_reduce.rb +2 -2
  82. data/lib/mongoid/contextual/memory.rb +285 -58
  83. data/lib/mongoid/contextual/mongo/documents_loader.rb +177 -0
  84. data/lib/mongoid/contextual/mongo.rb +521 -333
  85. data/lib/mongoid/contextual/none.rb +193 -20
  86. data/lib/mongoid/contextual/queryable.rb +1 -1
  87. data/lib/mongoid/contextual.rb +14 -2
  88. data/lib/mongoid/copyable.rb +32 -8
  89. data/lib/mongoid/criteria/findable.rb +8 -5
  90. data/lib/mongoid/criteria/includable.rb +27 -22
  91. data/lib/mongoid/criteria/marshalable.rb +10 -2
  92. data/lib/mongoid/criteria/permission.rb +1 -1
  93. data/lib/mongoid/criteria/queryable/aggregable.rb +2 -2
  94. data/lib/mongoid/criteria/queryable/extensions/array.rb +3 -16
  95. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +25 -4
  96. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +2 -2
  97. data/lib/mongoid/criteria/queryable/extensions/date.rb +6 -1
  98. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +6 -1
  99. data/lib/mongoid/criteria/queryable/extensions/hash.rb +1 -17
  100. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -9
  101. data/lib/mongoid/criteria/queryable/extensions/object.rb +2 -1
  102. data/lib/mongoid/criteria/queryable/extensions/range.rb +13 -5
  103. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +3 -3
  104. data/lib/mongoid/criteria/queryable/extensions/set.rb +1 -1
  105. data/lib/mongoid/criteria/queryable/extensions/string.rb +4 -14
  106. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +4 -12
  107. data/lib/mongoid/criteria/queryable/extensions/time.rb +6 -1
  108. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +6 -1
  109. data/lib/mongoid/criteria/queryable/key.rb +4 -4
  110. data/lib/mongoid/criteria/queryable/mergeable.rb +1 -1
  111. data/lib/mongoid/criteria/queryable/optional.rb +11 -17
  112. data/lib/mongoid/criteria/queryable/options.rb +2 -2
  113. data/lib/mongoid/criteria/queryable/pipeline.rb +1 -1
  114. data/lib/mongoid/criteria/queryable/selectable.rb +47 -38
  115. data/lib/mongoid/criteria/queryable/selector.rb +93 -8
  116. data/lib/mongoid/criteria/queryable/smash.rb +40 -7
  117. data/lib/mongoid/criteria/queryable/storable.rb +1 -1
  118. data/lib/mongoid/criteria/queryable.rb +12 -7
  119. data/lib/mongoid/criteria/scopable.rb +2 -2
  120. data/lib/mongoid/criteria/translator.rb +45 -0
  121. data/lib/mongoid/criteria.rb +20 -40
  122. data/lib/mongoid/deprecable.rb +36 -0
  123. data/lib/mongoid/deprecation.rb +25 -0
  124. data/lib/mongoid/document.rb +135 -36
  125. data/lib/mongoid/equality.rb +8 -8
  126. data/lib/mongoid/errors/create_collection_failure.rb +33 -0
  127. data/lib/mongoid/errors/document_not_found.rb +10 -6
  128. data/lib/mongoid/errors/drop_collection_failure.rb +27 -0
  129. data/lib/mongoid/errors/immutable_attribute.rb +26 -0
  130. data/lib/mongoid/errors/invalid_async_query_executor.rb +25 -0
  131. data/lib/mongoid/errors/invalid_config_option.rb +1 -1
  132. data/lib/mongoid/errors/invalid_dependent_strategy.rb +1 -1
  133. data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +23 -0
  134. data/lib/mongoid/errors/invalid_field.rb +6 -2
  135. data/lib/mongoid/errors/invalid_field_type.rb +26 -0
  136. data/lib/mongoid/errors/invalid_global_executor_concurrency.rb +22 -0
  137. data/lib/mongoid/errors/invalid_relation.rb +1 -1
  138. data/lib/mongoid/errors/invalid_relation_option.rb +1 -1
  139. data/lib/mongoid/errors/invalid_session_use.rb +1 -1
  140. data/lib/mongoid/errors/invalid_storage_options.rb +1 -1
  141. data/lib/mongoid/errors/invalid_storage_parent.rb +2 -0
  142. data/lib/mongoid/errors/mongoid_error.rb +3 -3
  143. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +1 -1
  144. data/lib/mongoid/errors/no_client_database.rb +1 -1
  145. data/lib/mongoid/errors/no_client_hosts.rb +1 -1
  146. data/lib/mongoid/errors/readonly_attribute.rb +1 -1
  147. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +1 -1
  148. data/lib/mongoid/errors/unknown_attribute.rb +1 -1
  149. data/lib/mongoid/errors.rb +6 -3
  150. data/lib/mongoid/extensions/array.rb +9 -7
  151. data/lib/mongoid/extensions/big_decimal.rb +33 -10
  152. data/lib/mongoid/extensions/binary.rb +42 -0
  153. data/lib/mongoid/extensions/boolean.rb +8 -2
  154. data/lib/mongoid/extensions/date.rb +26 -20
  155. data/lib/mongoid/extensions/date_time.rb +1 -1
  156. data/lib/mongoid/extensions/false_class.rb +1 -1
  157. data/lib/mongoid/extensions/float.rb +7 -4
  158. data/lib/mongoid/extensions/hash.rb +19 -8
  159. data/lib/mongoid/extensions/integer.rb +7 -4
  160. data/lib/mongoid/extensions/module.rb +1 -1
  161. data/lib/mongoid/extensions/object.rb +10 -8
  162. data/lib/mongoid/extensions/range.rb +41 -10
  163. data/lib/mongoid/extensions/regexp.rb +11 -4
  164. data/lib/mongoid/extensions/set.rb +11 -4
  165. data/lib/mongoid/extensions/string.rb +11 -22
  166. data/lib/mongoid/extensions/symbol.rb +4 -15
  167. data/lib/mongoid/extensions/time.rb +29 -16
  168. data/lib/mongoid/extensions/time_with_zone.rb +1 -2
  169. data/lib/mongoid/extensions/true_class.rb +1 -1
  170. data/lib/mongoid/extensions.rb +1 -0
  171. data/lib/mongoid/factory.rb +55 -7
  172. data/lib/mongoid/fields/foreign_key.rb +11 -4
  173. data/lib/mongoid/fields/localized.rb +19 -4
  174. data/lib/mongoid/fields/standard.rb +17 -7
  175. data/lib/mongoid/fields/validators/macro.rb +3 -9
  176. data/lib/mongoid/fields.rb +129 -20
  177. data/lib/mongoid/findable.rb +54 -24
  178. data/lib/mongoid/indexable/specification.rb +2 -2
  179. data/lib/mongoid/indexable/validators/options.rb +6 -2
  180. data/lib/mongoid/interceptable.rb +76 -15
  181. data/lib/mongoid/matchable.rb +1 -1
  182. data/lib/mongoid/matcher/eq_impl.rb +1 -1
  183. data/lib/mongoid/matcher/type.rb +1 -1
  184. data/lib/mongoid/matcher.rb +33 -13
  185. data/lib/mongoid/persistable/creatable.rb +19 -9
  186. data/lib/mongoid/persistable/deletable.rb +2 -2
  187. data/lib/mongoid/persistable/destroyable.rb +1 -1
  188. data/lib/mongoid/persistable/savable.rb +14 -2
  189. data/lib/mongoid/persistable/unsettable.rb +2 -2
  190. data/lib/mongoid/persistable/updatable.rb +69 -12
  191. data/lib/mongoid/persistable/upsertable.rb +21 -2
  192. data/lib/mongoid/persistable.rb +6 -3
  193. data/lib/mongoid/persistence_context.rb +63 -10
  194. data/lib/mongoid/query_cache.rb +13 -261
  195. data/lib/mongoid/railties/controller_runtime.rb +1 -1
  196. data/lib/mongoid/railties/database.rake +7 -2
  197. data/lib/mongoid/reloadable.rb +10 -8
  198. data/lib/mongoid/scopable.rb +15 -13
  199. data/lib/mongoid/selectable.rb +1 -2
  200. data/lib/mongoid/serializable.rb +10 -6
  201. data/lib/mongoid/shardable.rb +35 -11
  202. data/lib/mongoid/stateful.rb +57 -10
  203. data/lib/mongoid/tasks/database.rake +12 -0
  204. data/lib/mongoid/tasks/database.rb +20 -2
  205. data/lib/mongoid/threaded/lifecycle.rb +5 -5
  206. data/lib/mongoid/threaded.rb +42 -12
  207. data/lib/mongoid/timestamps/created.rb +1 -1
  208. data/lib/mongoid/timestamps/updated.rb +2 -2
  209. data/lib/mongoid/touchable.rb +2 -3
  210. data/lib/mongoid/traversable.rb +5 -4
  211. data/lib/mongoid/utils.rb +22 -0
  212. data/lib/mongoid/validatable/localizable.rb +1 -1
  213. data/lib/mongoid/validatable/macros.rb +5 -7
  214. data/lib/mongoid/validatable/presence.rb +2 -2
  215. data/lib/mongoid/validatable/uniqueness.rb +9 -8
  216. data/lib/mongoid/validatable.rb +9 -6
  217. data/lib/mongoid/version.rb +1 -1
  218. data/lib/mongoid/warnings.rb +19 -4
  219. data/lib/mongoid.rb +17 -3
  220. data/spec/config/mongoid.yml +16 -0
  221. data/spec/integration/app_spec.rb +10 -14
  222. data/spec/integration/associations/belongs_to_spec.rb +18 -0
  223. data/spec/integration/associations/embedded_spec.rb +15 -0
  224. data/spec/integration/associations/embeds_many_spec.rb +15 -2
  225. data/spec/integration/associations/embeds_one_spec.rb +18 -0
  226. data/spec/integration/associations/foreign_key_spec.rb +9 -0
  227. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +21 -0
  228. data/spec/integration/associations/has_one_spec.rb +97 -1
  229. data/spec/integration/associations/scope_option_spec.rb +1 -1
  230. data/spec/integration/callbacks_models.rb +132 -1
  231. data/spec/integration/callbacks_spec.rb +360 -4
  232. data/spec/integration/criteria/range_spec.rb +95 -1
  233. data/spec/integration/discriminator_key_spec.rb +118 -80
  234. data/spec/integration/dots_and_dollars_spec.rb +277 -0
  235. data/spec/integration/i18n_fallbacks_spec.rb +3 -32
  236. data/spec/integration/matcher_examples_spec.rb +20 -13
  237. data/spec/integration/matcher_operator_data/type_decimal.yml +3 -2
  238. data/spec/integration/matcher_operator_spec.rb +3 -5
  239. data/spec/integration/persistence/range_field_spec.rb +350 -0
  240. data/spec/mongoid/association/counter_cache_spec.rb +1 -1
  241. data/spec/mongoid/association/depending_spec.rb +9 -9
  242. data/spec/mongoid/association/eager_spec.rb +2 -1
  243. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +2 -1
  244. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +54 -0
  245. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +96 -9
  246. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +112 -0
  247. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +276 -65
  248. data/spec/mongoid/association/embedded/embeds_many_models.rb +158 -0
  249. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +12 -0
  250. data/spec/mongoid/association/embedded/embeds_many_spec.rb +68 -0
  251. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +25 -0
  252. data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +15 -2
  253. data/spec/mongoid/association/embedded/embeds_one_models.rb +19 -0
  254. data/spec/mongoid/association/embedded/embeds_one_spec.rb +28 -0
  255. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +2 -1
  256. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +54 -0
  257. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +15 -0
  258. data/spec/mongoid/association/referenced/belongs_to_models.rb +11 -0
  259. data/spec/mongoid/association/referenced/belongs_to_spec.rb +4 -20
  260. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +215 -228
  261. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +25 -0
  262. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +35 -2
  263. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +109 -0
  264. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +2 -56
  265. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +193 -177
  266. data/spec/mongoid/association/referenced/has_many_models.rb +3 -1
  267. data/spec/mongoid/association/referenced/has_many_spec.rb +25 -0
  268. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +2 -2
  269. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +107 -1
  270. data/spec/mongoid/association/referenced/has_one_models.rb +16 -0
  271. data/spec/mongoid/association/syncable_spec.rb +15 -1
  272. data/spec/mongoid/atomic/paths_spec.rb +0 -14
  273. data/spec/mongoid/attributes/nested_spec.rb +80 -11
  274. data/spec/mongoid/attributes/nested_spec_models.rb +48 -0
  275. data/spec/mongoid/attributes/projector_spec.rb +1 -5
  276. data/spec/mongoid/attributes_spec.rb +554 -33
  277. data/spec/mongoid/cacheable_spec.rb +3 -3
  278. data/spec/mongoid/changeable_spec.rb +429 -37
  279. data/spec/mongoid/clients/factory_spec.rb +23 -30
  280. data/spec/mongoid/clients/sessions_spec.rb +0 -38
  281. data/spec/mongoid/clients_spec.rb +179 -15
  282. data/spec/mongoid/collection_configurable_spec.rb +158 -0
  283. data/spec/mongoid/config/defaults_spec.rb +160 -0
  284. data/spec/mongoid/config_spec.rb +220 -30
  285. data/spec/mongoid/contextual/aggregable/memory_spec.rb +396 -158
  286. data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
  287. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
  288. data/spec/mongoid/contextual/map_reduce_spec.rb +2 -16
  289. data/spec/mongoid/contextual/memory_spec.rb +850 -88
  290. data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +187 -0
  291. data/spec/mongoid/contextual/mongo_spec.rb +1570 -413
  292. data/spec/mongoid/contextual/none_spec.rb +60 -21
  293. data/spec/mongoid/copyable_spec.rb +453 -11
  294. data/spec/mongoid/criteria/findable_spec.rb +86 -210
  295. data/spec/mongoid/criteria/includable_spec.rb +1492 -0
  296. data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
  297. data/spec/mongoid/criteria/marshalable_spec.rb +18 -1
  298. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +7 -19
  299. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +134 -26
  300. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +11 -0
  301. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +11 -0
  302. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +0 -15
  303. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +73 -7
  304. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +4 -69
  305. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +0 -59
  306. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +11 -0
  307. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +11 -0
  308. data/spec/mongoid/criteria/queryable/optional_spec.rb +15 -484
  309. data/spec/mongoid/criteria/queryable/options_spec.rb +1 -1
  310. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +469 -0
  311. data/spec/mongoid/criteria/queryable/selectable_spec.rb +78 -86
  312. data/spec/mongoid/criteria/queryable/selector_spec.rb +90 -5
  313. data/spec/mongoid/criteria/queryable/storable_spec.rb +72 -0
  314. data/spec/mongoid/criteria/translator_spec.rb +132 -0
  315. data/spec/mongoid/criteria_projection_spec.rb +1 -5
  316. data/spec/mongoid/criteria_spec.rb +469 -1205
  317. data/spec/mongoid/document_fields_spec.rb +173 -24
  318. data/spec/mongoid/document_spec.rb +32 -41
  319. data/spec/mongoid/errors/document_not_found_spec.rb +29 -2
  320. data/spec/mongoid/errors/invalid_field_spec.rb +1 -1
  321. data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
  322. data/spec/mongoid/errors/mongoid_error_spec.rb +3 -1
  323. data/spec/mongoid/errors/no_environment_spec.rb +3 -3
  324. data/spec/mongoid/errors/readonly_document_spec.rb +2 -2
  325. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +1 -1
  326. data/spec/mongoid/extensions/array_spec.rb +16 -2
  327. data/spec/mongoid/extensions/big_decimal_spec.rb +712 -212
  328. data/spec/mongoid/extensions/binary_spec.rb +44 -9
  329. data/spec/mongoid/extensions/boolean_spec.rb +68 -82
  330. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +7 -3
  331. data/spec/mongoid/extensions/date_spec.rb +71 -1
  332. data/spec/mongoid/extensions/date_time_spec.rb +15 -9
  333. data/spec/mongoid/extensions/float_spec.rb +53 -74
  334. data/spec/mongoid/extensions/hash_spec.rb +33 -3
  335. data/spec/mongoid/extensions/integer_spec.rb +50 -64
  336. data/spec/mongoid/extensions/range_spec.rb +255 -54
  337. data/spec/mongoid/extensions/regexp_spec.rb +58 -33
  338. data/spec/mongoid/extensions/set_spec.rb +106 -0
  339. data/spec/mongoid/extensions/string_spec.rb +53 -25
  340. data/spec/mongoid/extensions/symbol_spec.rb +18 -25
  341. data/spec/mongoid/extensions/time_spec.rb +639 -106
  342. data/spec/mongoid/extensions/time_with_zone_spec.rb +24 -83
  343. data/spec/mongoid/factory_spec.rb +61 -1
  344. data/spec/mongoid/fields/localized_spec.rb +80 -37
  345. data/spec/mongoid/fields_spec.rb +500 -84
  346. data/spec/mongoid/findable_spec.rb +450 -58
  347. data/spec/mongoid/indexable/specification_spec.rb +2 -2
  348. data/spec/mongoid/indexable_spec.rb +55 -30
  349. data/spec/mongoid/interceptable_spec.rb +599 -8
  350. data/spec/mongoid/interceptable_spec_models.rb +235 -4
  351. data/spec/mongoid/matcher/extract_attribute_spec.rb +1 -5
  352. data/spec/mongoid/mongoizable_spec.rb +285 -0
  353. data/spec/mongoid/persistable/creatable_spec.rb +2 -2
  354. data/spec/mongoid/persistable/deletable_spec.rb +28 -8
  355. data/spec/mongoid/persistable/destroyable_spec.rb +28 -8
  356. data/spec/mongoid/persistable/incrementable_spec.rb +37 -0
  357. data/spec/mongoid/persistable/logical_spec.rb +37 -0
  358. data/spec/mongoid/persistable/poppable_spec.rb +36 -0
  359. data/spec/mongoid/persistable/pullable_spec.rb +72 -0
  360. data/spec/mongoid/persistable/pushable_spec.rb +72 -0
  361. data/spec/mongoid/persistable/renamable_spec.rb +36 -0
  362. data/spec/mongoid/persistable/savable_spec.rb +96 -0
  363. data/spec/mongoid/persistable/settable_spec.rb +37 -0
  364. data/spec/mongoid/persistable/unsettable_spec.rb +36 -0
  365. data/spec/mongoid/persistable/updatable_spec.rb +20 -28
  366. data/spec/mongoid/persistable/upsertable_spec.rb +89 -1
  367. data/spec/mongoid/persistence_context_spec.rb +57 -58
  368. data/spec/mongoid/query_cache_middleware_spec.rb +0 -18
  369. data/spec/mongoid/query_cache_spec.rb +56 -215
  370. data/spec/mongoid/reloadable_spec.rb +83 -6
  371. data/spec/mongoid/scopable_spec.rb +91 -1
  372. data/spec/mongoid/serializable_spec.rb +9 -30
  373. data/spec/mongoid/shardable_models.rb +14 -0
  374. data/spec/mongoid/shardable_spec.rb +157 -51
  375. data/spec/mongoid/stateful_spec.rb +150 -8
  376. data/spec/mongoid/tasks/database_rake_spec.rb +74 -0
  377. data/spec/mongoid/tasks/database_spec.rb +127 -0
  378. data/spec/mongoid/timestamps_spec.rb +392 -4
  379. data/spec/mongoid/timestamps_spec_models.rb +67 -0
  380. data/spec/mongoid/touchable_spec.rb +390 -2
  381. data/spec/mongoid/touchable_spec_models.rb +14 -8
  382. data/spec/mongoid/traversable_spec.rb +13 -35
  383. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  384. data/spec/mongoid/validatable/uniqueness_spec.rb +58 -31
  385. data/spec/mongoid/warnings_spec.rb +35 -0
  386. data/spec/mongoid_spec.rb +34 -10
  387. data/spec/rails/controller_extension/controller_runtime_spec.rb +2 -2
  388. data/spec/rails/mongoid_spec.rb +4 -16
  389. data/spec/shared/lib/mrss/lite_constraints.rb +8 -0
  390. data/spec/shared/shlib/server.sh +5 -5
  391. data/spec/spec_helper.rb +5 -0
  392. data/spec/support/constraints.rb +24 -0
  393. data/spec/support/immutable_ids.rb +118 -0
  394. data/spec/support/macros.rb +78 -0
  395. data/spec/support/models/artist.rb +0 -1
  396. data/spec/support/models/augmentation.rb +12 -0
  397. data/spec/support/models/band.rb +4 -0
  398. data/spec/support/models/book.rb +1 -0
  399. data/spec/support/models/building.rb +2 -0
  400. data/spec/support/models/catalog.rb +24 -0
  401. data/spec/support/models/circus.rb +3 -0
  402. data/spec/support/models/cover.rb +10 -0
  403. data/spec/support/models/fanatic.rb +8 -0
  404. data/spec/support/models/implant.rb +9 -0
  405. data/spec/support/models/label.rb +2 -0
  406. data/spec/support/models/passport.rb +9 -0
  407. data/spec/support/models/person.rb +2 -0
  408. data/spec/support/models/player.rb +2 -0
  409. data/spec/support/models/powerup.rb +12 -0
  410. data/spec/support/models/product.rb +1 -0
  411. data/spec/support/models/purse.rb +9 -0
  412. data/spec/support/models/registry.rb +1 -0
  413. data/spec/support/models/school.rb +14 -0
  414. data/spec/support/models/shield.rb +18 -0
  415. data/spec/support/models/student.rb +14 -0
  416. data/spec/support/models/weapon.rb +12 -0
  417. data.tar.gz.sig +0 -0
  418. metadata +720 -638
  419. metadata.gz.sig +0 -0
  420. data/lib/mongoid/errors/eager_load.rb +0 -23
  421. data/lib/mongoid/errors/invalid_value.rb +0 -17
  422. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +0 -60
  423. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +0 -60
  424. data/spec/mongoid/errors/eager_load_spec.rb +0 -31
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "spec_helper"
4
+ require_relative '../embeds_many_models.rb'
4
5
 
5
6
  describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
6
7
 
@@ -1861,51 +1862,56 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
1861
1862
  end
1862
1863
  end
1863
1864
 
1864
- 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") }
1865
1869
 
1866
- let(:person) do
1867
- Person.new
1868
- end
1869
-
1870
- let(:address_one) do
1871
- Address.new(street: "first")
1872
- end
1870
+ before do
1871
+ person.addresses << [ address_one, address_two ]
1872
+ end
1873
1873
 
1874
- let(:address_two) do
1875
- Address.new(street: "second")
1876
- 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
1877
1879
 
1878
- before do
1879
- person.addresses << [ address_one, address_two ]
1880
- 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
1881
1884
 
1882
- 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
1883
1888
 
1884
- let!(:deleted) do
1885
- person.addresses.delete(address_one)
1886
- end
1889
+ it 'reindexes the relation' do
1890
+ expect(address_two._index).to eq(0)
1891
+ end
1887
1892
 
1888
- it "deletes the document" do
1889
- expect(person.addresses).to eq([ address_two ])
1890
- end
1893
+ it 'returns the document' do
1894
+ expect(deleted).to eq(address_one)
1895
+ end
1896
+ end
1891
1897
 
1892
- it "deletes the document from the unscoped" do
1893
- 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
1894
1903
  end
1895
1904
 
1896
- it "reindexes the relation" do
1897
- expect(address_two._index).to eq(0)
1898
- end
1905
+ context 'when the root document is unpersisted' do
1906
+ let(:person) { Person.new }
1899
1907
 
1900
- it "returns the document" do
1901
- expect(deleted).to eq(address_one)
1908
+ it_behaves_like 'deleting from the collection'
1902
1909
  end
1903
- end
1904
1910
 
1905
- context "when the document does not exist" do
1911
+ context 'when the root document is persisted' do
1912
+ let(:person) { Person.create }
1906
1913
 
1907
- it "returns nil" do
1908
- expect(person.addresses.delete(Address.new)).to be_nil
1914
+ it_behaves_like 'deleting from the collection'
1909
1915
  end
1910
1916
  end
1911
1917
  end
@@ -2209,6 +2215,79 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
2209
2215
  end
2210
2216
  end
2211
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
2212
2291
  end
2213
2292
  end
2214
2293
 
@@ -2278,32 +2357,22 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
2278
2357
  context "when the id does not match" do
2279
2358
 
2280
2359
  context "when config set to raise error" do
2281
-
2282
- before do
2283
- Mongoid.raise_not_found_error = true
2284
- end
2360
+ config_override :raise_not_found_error, true
2285
2361
 
2286
2362
  it "raises an error" do
2287
2363
  expect {
2288
2364
  person.addresses.find(BSON::ObjectId.new)
2289
- }.to raise_error(Mongoid::Errors::DocumentNotFound)
2365
+ }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Address with id\(s\)/)
2290
2366
  end
2291
2367
  end
2292
2368
 
2293
2369
  context "when config set not to raise error" do
2370
+ config_override :raise_not_found_error, false
2294
2371
 
2295
2372
  let(:address) do
2296
2373
  person.addresses.find(BSON::ObjectId.new)
2297
2374
  end
2298
2375
 
2299
- before do
2300
- Mongoid.raise_not_found_error = false
2301
- end
2302
-
2303
- after do
2304
- Mongoid.raise_not_found_error = true
2305
- end
2306
-
2307
2376
  it "returns nil" do
2308
2377
  expect(address).to be_nil
2309
2378
  end
@@ -2327,32 +2396,22 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
2327
2396
  context "when the ids do not match" do
2328
2397
 
2329
2398
  context "when config set to raise error" do
2330
-
2331
- before do
2332
- Mongoid.raise_not_found_error = true
2333
- end
2399
+ config_override :raise_not_found_error, true
2334
2400
 
2335
2401
  it "raises an error" do
2336
2402
  expect {
2337
2403
  person.addresses.find([ BSON::ObjectId.new ])
2338
- }.to raise_error(Mongoid::Errors::DocumentNotFound)
2404
+ }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Address with id\(s\)/)
2339
2405
  end
2340
2406
  end
2341
2407
 
2342
2408
  context "when config set not to raise error" do
2409
+ config_override :raise_not_found_error, false
2343
2410
 
2344
2411
  let(:addresses) do
2345
2412
  person.addresses.find([ BSON::ObjectId.new ])
2346
2413
  end
2347
2414
 
2348
- before do
2349
- Mongoid.raise_not_found_error = false
2350
- end
2351
-
2352
- after do
2353
- Mongoid.raise_not_found_error = true
2354
- end
2355
-
2356
2415
  it "returns an empty array" do
2357
2416
  expect(addresses).to be_empty
2358
2417
  end
@@ -3460,7 +3519,7 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
3460
3519
 
3461
3520
  describe "replacing the entire embedded list" do
3462
3521
 
3463
- 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
3464
3523
 
3465
3524
  let(:person) do
3466
3525
  Person.create!
@@ -3481,7 +3540,7 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
3481
3540
  end
3482
3541
  end
3483
3542
 
3484
- 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
3485
3544
 
3486
3545
  let(:person) do
3487
3546
  Person.create!
@@ -3502,7 +3561,7 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
3502
3561
  end
3503
3562
  end
3504
3563
 
3505
- 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
3506
3565
 
3507
3566
  let(:person) do
3508
3567
  Person.create!
@@ -3526,7 +3585,7 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
3526
3585
 
3527
3586
  describe "appending to the embedded list" do
3528
3587
 
3529
- 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
3530
3589
 
3531
3590
  let(:person) do
3532
3591
  Person.create! phone_numbers: []
@@ -3545,7 +3604,7 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
3545
3604
  end
3546
3605
  end
3547
3606
 
3548
- 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
3549
3608
 
3550
3609
  let(:person) do
3551
3610
  Person.create! phone_numbers: []
@@ -3564,7 +3623,7 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
3564
3623
  end
3565
3624
  end
3566
3625
 
3567
- 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
3568
3627
 
3569
3628
  let(:person) do
3570
3629
  Person.create! phone_numbers: []
@@ -3959,6 +4018,28 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
3959
4018
  end
3960
4019
  end
3961
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
+
3962
4043
  context "when adding a document" do
3963
4044
 
3964
4045
  let(:person) do
@@ -4490,7 +4571,7 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
4490
4571
  before do
4491
4572
  band.collection.
4492
4573
  find(_id: band.id).
4493
- update_one("$set" => { records: [{ name: "Moderat" }]})
4574
+ update_one("$set" => { records: [{ _id: BSON::ObjectId.new, name: "Moderat" }]})
4494
4575
  end
4495
4576
 
4496
4577
  context "when loading the documents" do
@@ -4649,4 +4730,134 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
4649
4730
  end
4650
4731
  end
4651
4732
  end
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
+
4783
+ context "when using assign_attributes with an already populated array" do
4784
+ let(:post) { EmmPost.create! }
4785
+
4786
+ before do
4787
+ post.assign_attributes(company_tags: [{id: BSON::ObjectId.new, title: 'a'}],
4788
+ user_tags: [{id: BSON::ObjectId.new, title: 'b'}])
4789
+ post.save!
4790
+ post.reload
4791
+ post.assign_attributes(company_tags: [{id: BSON::ObjectId.new, title: 'c'}],
4792
+ user_tags: [])
4793
+ post.save!
4794
+ post.reload
4795
+ end
4796
+
4797
+ it "has the correct embedded documents" do
4798
+ expect(post.company_tags.length).to eq(1)
4799
+ expect(post.company_tags.first.title).to eq("c")
4800
+ end
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
4652
4863
  end
@@ -67,3 +67,161 @@ class EmmOuter
67
67
 
68
68
  field :level, :type => Integer
69
69
  end
70
+
71
+ class EmmCustomerAddress
72
+ include Mongoid::Document
73
+
74
+ embedded_in :addressable, polymorphic: true, inverse_of: :work_address
75
+ end
76
+
77
+ class EmmFriend
78
+ include Mongoid::Document
79
+
80
+ embedded_in :befriendable, polymorphic: true
81
+ end
82
+
83
+ class EmmCustomer
84
+ include Mongoid::Document
85
+
86
+ embeds_one :home_address, class_name: 'EmmCustomerAddress', as: :addressable
87
+ embeds_one :work_address, class_name: 'EmmCustomerAddress', as: :addressable
88
+
89
+ embeds_many :close_friends, class_name: 'EmmFriend', as: :befriendable
90
+ embeds_many :acquaintances, class_name: 'EmmFriend', as: :befriendable
91
+ end
92
+
93
+ class EmmUser
94
+ include Mongoid::Document
95
+ include Mongoid::Timestamps
96
+
97
+ embeds_many :orders, class_name: 'EmmOrder'
98
+ end
99
+
100
+ class EmmOrder
101
+ include Mongoid::Document
102
+
103
+ field :sku
104
+ field :amount, type: Integer
105
+
106
+ embedded_in :user, class_name: 'EmmUser'
107
+ end
108
+
109
+ module EmmSpec
110
+ # There is also a top-level Car class defined.
111
+ class Car
112
+ include Mongoid::Document
113
+
114
+ embeds_many :doors
115
+ end
116
+
117
+ class Door
118
+ include Mongoid::Document
119
+
120
+ embedded_in :car
121
+ end
122
+
123
+ class Tank
124
+ include Mongoid::Document
125
+
126
+ embeds_many :guns
127
+ embeds_many :emm_turrets
128
+ # This association references a model that is not in our module,
129
+ # and it does not define class_name hence Mongoid will not be able to
130
+ # figure out the inverse for this association.
131
+ embeds_many :emm_hatches
132
+
133
+ # class_name is intentionally unqualified, references a class in the
134
+ # same module. Rails permits class_name to be unqualified like this.
135
+ embeds_many :launchers, class_name: 'Launcher'
136
+ end
137
+
138
+ class Gun
139
+ include Mongoid::Document
140
+
141
+ embedded_in :tank
142
+ end
143
+
144
+ class Launcher
145
+ include Mongoid::Document
146
+
147
+ # class_name is intentionally unqualified.
148
+ embedded_in :tank, class_name: 'Tank'
149
+ end
150
+ end
151
+
152
+ # This is intentionally on top level.
153
+ class EmmTurret
154
+ include Mongoid::Document
155
+
156
+ embedded_in :tank, class_name: 'EmmSpec::Tank'
157
+ end
158
+
159
+ # This is intentionally on top level.
160
+ class EmmHatch
161
+ include Mongoid::Document
162
+
163
+ # No :class_name option on this association intentionally.
164
+ embedded_in :tank
165
+ end
166
+
167
+ class EmmPost
168
+ include Mongoid::Document
169
+
170
+ embeds_many :company_tags, class_name: "EmmCompanyTag"
171
+ embeds_many :user_tags, class_name: "EmmUserTag"
172
+ end
173
+
174
+
175
+ class EmmCompanyTag
176
+ include Mongoid::Document
177
+
178
+ field :title, type: String
179
+
180
+ embedded_in :post, class_name: "EmmPost"
181
+ end
182
+
183
+
184
+ class EmmUserTag
185
+ include Mongoid::Document
186
+
187
+ field :title, type: String
188
+
189
+ embedded_in :post, class_name: "EmmPost"
190
+ end
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