mongoid 7.4.0 → 8.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (391) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +3 -3
  4. data/lib/config/locales/en.yml +52 -28
  5. data/lib/mongoid/association/accessors.rb +38 -9
  6. data/lib/mongoid/association/bindable.rb +50 -2
  7. data/lib/mongoid/association/builders.rb +4 -2
  8. data/lib/mongoid/association/constrainable.rb +0 -1
  9. data/lib/mongoid/association/eager_loadable.rb +29 -7
  10. data/lib/mongoid/association/embedded/batchable.rb +53 -13
  11. data/lib/mongoid/association/embedded/cyclic.rb +1 -1
  12. data/lib/mongoid/association/embedded/embedded_in/binding.rb +24 -2
  13. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +2 -2
  14. data/lib/mongoid/association/embedded/embedded_in.rb +3 -2
  15. data/lib/mongoid/association/embedded/embeds_many/binding.rb +1 -0
  16. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +1 -1
  17. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +50 -28
  18. data/lib/mongoid/association/embedded/embeds_many.rb +2 -2
  19. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +18 -4
  20. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +23 -4
  21. data/lib/mongoid/association/embedded/embeds_one.rb +3 -3
  22. data/lib/mongoid/association/macros.rb +22 -1
  23. data/lib/mongoid/association/many.rb +11 -7
  24. data/lib/mongoid/association/nested/many.rb +5 -4
  25. data/lib/mongoid/association/nested/nested_buildable.rb +4 -4
  26. data/lib/mongoid/association/nested/one.rb +5 -5
  27. data/lib/mongoid/association/one.rb +2 -2
  28. data/lib/mongoid/association/options.rb +9 -9
  29. data/lib/mongoid/association/proxy.rb +14 -3
  30. data/lib/mongoid/association/referenced/auto_save.rb +4 -3
  31. data/lib/mongoid/association/referenced/belongs_to/binding.rb +1 -0
  32. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +1 -1
  33. data/lib/mongoid/association/referenced/belongs_to/proxy.rb +5 -6
  34. data/lib/mongoid/association/referenced/belongs_to.rb +2 -2
  35. data/lib/mongoid/association/referenced/counter_cache.rb +10 -10
  36. data/lib/mongoid/association/referenced/eager.rb +2 -2
  37. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +66 -13
  38. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +6 -3
  39. data/lib/mongoid/association/referenced/has_many/enumerable.rb +20 -24
  40. data/lib/mongoid/association/referenced/has_many/proxy.rb +24 -18
  41. data/lib/mongoid/association/referenced/has_many.rb +3 -3
  42. data/lib/mongoid/association/referenced/has_one/buildable.rb +1 -1
  43. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +5 -5
  44. data/lib/mongoid/association/referenced/has_one/proxy.rb +9 -12
  45. data/lib/mongoid/association/referenced/has_one.rb +3 -3
  46. data/lib/mongoid/association/referenced/syncable.rb +4 -4
  47. data/lib/mongoid/association/reflections.rb +2 -2
  48. data/lib/mongoid/association/relatable.rb +44 -10
  49. data/lib/mongoid/association.rb +5 -5
  50. data/lib/mongoid/atomic/modifiers.rb +2 -2
  51. data/lib/mongoid/atomic/paths/embedded/many.rb +19 -0
  52. data/lib/mongoid/attributes/dynamic.rb +3 -3
  53. data/lib/mongoid/attributes/nested.rb +5 -5
  54. data/lib/mongoid/attributes/processing.rb +10 -3
  55. data/lib/mongoid/attributes/projector.rb +1 -1
  56. data/lib/mongoid/attributes/readonly.rb +2 -2
  57. data/lib/mongoid/attributes.rb +43 -40
  58. data/lib/mongoid/cacheable.rb +2 -2
  59. data/lib/mongoid/changeable.rb +42 -7
  60. data/lib/mongoid/clients/options.rb +5 -1
  61. data/lib/mongoid/clients/sessions.rb +2 -14
  62. data/lib/mongoid/clients/validators/storage.rb +3 -3
  63. data/lib/mongoid/config/environment.rb +20 -4
  64. data/lib/mongoid/config/validators/client.rb +6 -6
  65. data/lib/mongoid/config.rb +32 -17
  66. data/lib/mongoid/contextual/aggregable/memory.rb +24 -16
  67. data/lib/mongoid/contextual/aggregable/mongo.rb +5 -5
  68. data/lib/mongoid/contextual/aggregable/none.rb +1 -1
  69. data/lib/mongoid/contextual/atomic.rb +1 -1
  70. data/lib/mongoid/contextual/geo_near.rb +7 -7
  71. data/lib/mongoid/contextual/map_reduce.rb +2 -2
  72. data/lib/mongoid/contextual/memory.rb +180 -21
  73. data/lib/mongoid/contextual/mongo.rb +237 -217
  74. data/lib/mongoid/contextual/none.rb +67 -5
  75. data/lib/mongoid/contextual/queryable.rb +1 -1
  76. data/lib/mongoid/contextual.rb +2 -2
  77. data/lib/mongoid/copyable.rb +32 -8
  78. data/lib/mongoid/criteria/findable.rb +7 -4
  79. data/lib/mongoid/criteria/includable.rb +24 -20
  80. data/lib/mongoid/criteria/marshalable.rb +10 -2
  81. data/lib/mongoid/criteria/permission.rb +1 -1
  82. data/lib/mongoid/criteria/queryable/aggregable.rb +2 -2
  83. data/lib/mongoid/criteria/queryable/extensions/array.rb +2 -13
  84. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +25 -4
  85. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +2 -2
  86. data/lib/mongoid/criteria/queryable/extensions/date.rb +6 -1
  87. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +6 -1
  88. data/lib/mongoid/criteria/queryable/extensions/hash.rb +0 -14
  89. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -1
  90. data/lib/mongoid/criteria/queryable/extensions/object.rb +2 -1
  91. data/lib/mongoid/criteria/queryable/extensions/range.rb +13 -5
  92. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +3 -3
  93. data/lib/mongoid/criteria/queryable/extensions/set.rb +1 -1
  94. data/lib/mongoid/criteria/queryable/extensions/string.rb +3 -3
  95. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +4 -2
  96. data/lib/mongoid/criteria/queryable/extensions/time.rb +6 -1
  97. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +6 -1
  98. data/lib/mongoid/criteria/queryable/key.rb +3 -3
  99. data/lib/mongoid/criteria/queryable/mergeable.rb +21 -0
  100. data/lib/mongoid/criteria/queryable/optional.rb +5 -11
  101. data/lib/mongoid/criteria/queryable/options.rb +2 -2
  102. data/lib/mongoid/criteria/queryable/pipeline.rb +1 -1
  103. data/lib/mongoid/criteria/queryable/selectable.rb +31 -37
  104. data/lib/mongoid/criteria/queryable/selector.rb +92 -7
  105. data/lib/mongoid/criteria/queryable/smash.rb +40 -7
  106. data/lib/mongoid/criteria/queryable.rb +12 -7
  107. data/lib/mongoid/criteria/scopable.rb +2 -2
  108. data/lib/mongoid/criteria.rb +15 -35
  109. data/lib/mongoid/deprecable.rb +36 -0
  110. data/lib/mongoid/deprecation.rb +25 -0
  111. data/lib/mongoid/document.rb +98 -34
  112. data/lib/mongoid/equality.rb +12 -12
  113. data/lib/mongoid/errors/document_not_found.rb +33 -12
  114. data/lib/mongoid/errors/invalid_config_option.rb +1 -1
  115. data/lib/mongoid/errors/invalid_dependent_strategy.rb +1 -1
  116. data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +23 -0
  117. data/lib/mongoid/errors/invalid_field.rb +6 -2
  118. data/lib/mongoid/errors/invalid_field_type.rb +26 -0
  119. data/lib/mongoid/errors/invalid_relation.rb +1 -1
  120. data/lib/mongoid/errors/invalid_relation_option.rb +1 -1
  121. data/lib/mongoid/errors/invalid_session_use.rb +1 -1
  122. data/lib/mongoid/errors/invalid_storage_options.rb +1 -1
  123. data/lib/mongoid/errors/mongoid_error.rb +3 -3
  124. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +1 -1
  125. data/lib/mongoid/errors/no_client_database.rb +1 -1
  126. data/lib/mongoid/errors/no_client_hosts.rb +1 -1
  127. data/lib/mongoid/errors/readonly_attribute.rb +1 -1
  128. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +1 -1
  129. data/lib/mongoid/errors/unknown_attribute.rb +1 -1
  130. data/lib/mongoid/errors.rb +2 -2
  131. data/lib/mongoid/extensions/array.rb +9 -7
  132. data/lib/mongoid/extensions/big_decimal.rb +33 -10
  133. data/lib/mongoid/extensions/binary.rb +42 -0
  134. data/lib/mongoid/extensions/boolean.rb +8 -2
  135. data/lib/mongoid/extensions/date.rb +26 -20
  136. data/lib/mongoid/extensions/date_time.rb +1 -1
  137. data/lib/mongoid/extensions/false_class.rb +1 -1
  138. data/lib/mongoid/extensions/float.rb +7 -4
  139. data/lib/mongoid/extensions/hash.rb +13 -6
  140. data/lib/mongoid/extensions/integer.rb +7 -4
  141. data/lib/mongoid/extensions/module.rb +1 -1
  142. data/lib/mongoid/extensions/object.rb +8 -6
  143. data/lib/mongoid/extensions/range.rb +41 -10
  144. data/lib/mongoid/extensions/regexp.rb +11 -4
  145. data/lib/mongoid/extensions/set.rb +11 -4
  146. data/lib/mongoid/extensions/string.rb +11 -22
  147. data/lib/mongoid/extensions/symbol.rb +4 -15
  148. data/lib/mongoid/extensions/time.rb +27 -16
  149. data/lib/mongoid/extensions/time_with_zone.rb +1 -2
  150. data/lib/mongoid/extensions/true_class.rb +1 -1
  151. data/lib/mongoid/extensions.rb +1 -0
  152. data/lib/mongoid/factory.rb +42 -7
  153. data/lib/mongoid/fields/foreign_key.rb +11 -4
  154. data/lib/mongoid/fields/localized.rb +9 -4
  155. data/lib/mongoid/fields/standard.rb +7 -7
  156. data/lib/mongoid/fields/validators/macro.rb +3 -9
  157. data/lib/mongoid/fields.rb +201 -35
  158. data/lib/mongoid/findable.rb +34 -13
  159. data/lib/mongoid/indexable/specification.rb +2 -2
  160. data/lib/mongoid/indexable/validators/options.rb +6 -2
  161. data/lib/mongoid/interceptable.rb +73 -13
  162. data/lib/mongoid/matchable.rb +1 -1
  163. data/lib/mongoid/matcher.rb +12 -7
  164. data/lib/mongoid/persistable/creatable.rb +18 -9
  165. data/lib/mongoid/persistable/deletable.rb +1 -1
  166. data/lib/mongoid/persistable/destroyable.rb +1 -1
  167. data/lib/mongoid/persistable/savable.rb +2 -2
  168. data/lib/mongoid/persistable/unsettable.rb +1 -1
  169. data/lib/mongoid/persistable/updatable.rb +19 -12
  170. data/lib/mongoid/persistable/upsertable.rb +2 -2
  171. data/lib/mongoid/persistable.rb +3 -3
  172. data/lib/mongoid/persistence_context.rb +63 -10
  173. data/lib/mongoid/query_cache.rb +8 -260
  174. data/lib/mongoid/railties/controller_runtime.rb +1 -1
  175. data/lib/mongoid/reloadable.rb +7 -3
  176. data/lib/mongoid/scopable.rb +26 -22
  177. data/lib/mongoid/selectable.rb +1 -2
  178. data/lib/mongoid/serializable.rb +10 -6
  179. data/lib/mongoid/stateful.rb +35 -9
  180. data/lib/mongoid/tasks/database.rb +0 -2
  181. data/lib/mongoid/threaded/lifecycle.rb +5 -5
  182. data/lib/mongoid/threaded.rb +12 -12
  183. data/lib/mongoid/timestamps/created.rb +1 -1
  184. data/lib/mongoid/timestamps/updated.rb +2 -2
  185. data/lib/mongoid/touchable.rb +2 -3
  186. data/lib/mongoid/traversable.rb +8 -4
  187. data/lib/mongoid/validatable/localizable.rb +1 -1
  188. data/lib/mongoid/validatable/macros.rb +0 -2
  189. data/lib/mongoid/validatable/presence.rb +2 -2
  190. data/lib/mongoid/validatable/uniqueness.rb +9 -8
  191. data/lib/mongoid/validatable.rb +6 -6
  192. data/lib/mongoid/version.rb +1 -1
  193. data/lib/mongoid/warnings.rb +28 -0
  194. data/lib/mongoid.rb +2 -0
  195. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +11 -5
  196. data/spec/config/mongoid.yml +16 -0
  197. data/spec/config/mongoid_with_schema_map_uuid.yml +27 -0
  198. data/spec/integration/app_spec.rb +28 -26
  199. data/spec/integration/associations/belongs_to_spec.rb +18 -0
  200. data/spec/integration/associations/embedded_dirty_spec.rb +28 -0
  201. data/spec/integration/associations/embedded_spec.rb +15 -0
  202. data/spec/integration/associations/embeds_many_spec.rb +15 -2
  203. data/spec/integration/associations/embeds_one_spec.rb +18 -0
  204. data/spec/integration/associations/foreign_key_spec.rb +9 -0
  205. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +21 -0
  206. data/spec/integration/associations/has_one_spec.rb +97 -1
  207. data/spec/integration/associations/scope_option_spec.rb +1 -1
  208. data/spec/integration/callbacks_models.rb +95 -1
  209. data/spec/integration/callbacks_spec.rb +226 -4
  210. data/spec/integration/criteria/range_spec.rb +95 -1
  211. data/spec/integration/discriminator_key_spec.rb +115 -76
  212. data/spec/integration/dots_and_dollars_spec.rb +277 -0
  213. data/spec/integration/i18n_fallbacks_spec.rb +1 -17
  214. data/spec/integration/matcher_examples_spec.rb +20 -13
  215. data/spec/integration/matcher_operator_data/type_decimal.yml +3 -2
  216. data/spec/integration/matcher_operator_spec.rb +3 -5
  217. data/spec/integration/persistence/range_field_spec.rb +350 -0
  218. data/spec/lite_spec_helper.rb +1 -1
  219. data/spec/mongoid/association/counter_cache_spec.rb +1 -1
  220. data/spec/mongoid/association/depending_spec.rb +9 -9
  221. data/spec/mongoid/association/eager_spec.rb +2 -1
  222. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +2 -1
  223. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +54 -0
  224. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +69 -9
  225. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +112 -0
  226. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +219 -8
  227. data/spec/mongoid/association/embedded/embeds_many_models.rb +157 -0
  228. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +12 -0
  229. data/spec/mongoid/association/embedded/embeds_many_spec.rb +68 -0
  230. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +25 -0
  231. data/spec/mongoid/association/embedded/embeds_one_models.rb +19 -0
  232. data/spec/mongoid/association/embedded/embeds_one_spec.rb +28 -0
  233. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +2 -1
  234. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +54 -0
  235. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +15 -0
  236. data/spec/mongoid/association/referenced/belongs_to_models.rb +11 -0
  237. data/spec/mongoid/association/referenced/belongs_to_spec.rb +2 -2
  238. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +67 -4
  239. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +25 -0
  240. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +35 -2
  241. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +109 -0
  242. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +8 -8
  243. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +82 -13
  244. data/spec/mongoid/association/referenced/has_many_models.rb +3 -1
  245. data/spec/mongoid/association/referenced/has_many_spec.rb +25 -0
  246. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +2 -2
  247. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +107 -1
  248. data/spec/mongoid/association/referenced/has_one_models.rb +16 -0
  249. data/spec/mongoid/association/syncable_spec.rb +14 -0
  250. data/spec/mongoid/atomic/paths_spec.rb +0 -14
  251. data/spec/mongoid/atomic_spec.rb +22 -0
  252. data/spec/mongoid/attributes/nested_spec.rb +80 -11
  253. data/spec/mongoid/attributes/nested_spec_models.rb +48 -0
  254. data/spec/mongoid/attributes/projector_spec.rb +1 -5
  255. data/spec/mongoid/attributes_spec.rb +524 -27
  256. data/spec/mongoid/cacheable_spec.rb +3 -3
  257. data/spec/mongoid/changeable_spec.rb +130 -13
  258. data/spec/mongoid/clients/factory_spec.rb +34 -42
  259. data/spec/mongoid/clients/options_spec.rb +1 -0
  260. data/spec/mongoid/clients/sessions_spec.rb +0 -38
  261. data/spec/mongoid/clients_spec.rb +57 -2
  262. data/spec/mongoid/config/environment_spec.rb +39 -1
  263. data/spec/mongoid/config_spec.rb +104 -13
  264. data/spec/mongoid/contextual/aggregable/memory_spec.rb +396 -158
  265. data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
  266. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
  267. data/spec/mongoid/contextual/map_reduce_spec.rb +2 -16
  268. data/spec/mongoid/contextual/memory_spec.rb +1336 -69
  269. data/spec/mongoid/contextual/mongo_spec.rb +1105 -174
  270. data/spec/mongoid/contextual/none_spec.rb +38 -0
  271. data/spec/mongoid/copyable_spec.rb +451 -1
  272. data/spec/mongoid/criteria/findable_spec.rb +86 -210
  273. data/spec/mongoid/criteria/includable_spec.rb +1492 -0
  274. data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
  275. data/spec/mongoid/criteria/marshalable_spec.rb +18 -1
  276. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +7 -19
  277. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +134 -26
  278. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +11 -0
  279. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +11 -0
  280. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +0 -15
  281. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +73 -7
  282. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +11 -0
  283. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +11 -0
  284. data/spec/mongoid/criteria/queryable/optional_spec.rb +0 -484
  285. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +50 -0
  286. data/spec/mongoid/criteria/queryable/selectable_spec.rb +289 -124
  287. data/spec/mongoid/criteria/queryable/selector_spec.rb +14 -2
  288. data/spec/mongoid/criteria_projection_spec.rb +0 -1
  289. data/spec/mongoid/criteria_spec.rb +475 -1199
  290. data/spec/mongoid/document_fields_spec.rb +173 -24
  291. data/spec/mongoid/document_spec.rb +32 -41
  292. data/spec/mongoid/equality_spec.rb +12 -12
  293. data/spec/mongoid/errors/document_not_found_spec.rb +76 -0
  294. data/spec/mongoid/errors/invalid_field_spec.rb +1 -1
  295. data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
  296. data/spec/mongoid/errors/mongoid_error_spec.rb +3 -1
  297. data/spec/mongoid/errors/no_environment_spec.rb +3 -3
  298. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +1 -1
  299. data/spec/mongoid/extensions/array_spec.rb +16 -2
  300. data/spec/mongoid/extensions/big_decimal_spec.rb +712 -212
  301. data/spec/mongoid/extensions/binary_spec.rb +44 -9
  302. data/spec/mongoid/extensions/boolean_spec.rb +68 -82
  303. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +7 -3
  304. data/spec/mongoid/extensions/date_spec.rb +71 -1
  305. data/spec/mongoid/extensions/date_time_spec.rb +15 -9
  306. data/spec/mongoid/extensions/float_spec.rb +53 -74
  307. data/spec/mongoid/extensions/hash_spec.rb +30 -0
  308. data/spec/mongoid/extensions/integer_spec.rb +50 -64
  309. data/spec/mongoid/extensions/range_spec.rb +255 -54
  310. data/spec/mongoid/extensions/regexp_spec.rb +58 -33
  311. data/spec/mongoid/extensions/set_spec.rb +106 -0
  312. data/spec/mongoid/extensions/string_spec.rb +53 -25
  313. data/spec/mongoid/extensions/symbol_spec.rb +18 -25
  314. data/spec/mongoid/extensions/time_spec.rb +634 -66
  315. data/spec/mongoid/extensions/time_with_zone_spec.rb +17 -31
  316. data/spec/mongoid/factory_spec.rb +61 -1
  317. data/spec/mongoid/fields/localized_spec.rb +37 -12
  318. data/spec/mongoid/fields_spec.rb +321 -50
  319. data/spec/mongoid/findable_spec.rb +80 -15
  320. data/spec/mongoid/indexable/specification_spec.rb +2 -2
  321. data/spec/mongoid/indexable_spec.rb +39 -20
  322. data/spec/mongoid/interceptable_spec.rb +584 -5
  323. data/spec/mongoid/interceptable_spec_models.rb +235 -4
  324. data/spec/mongoid/matcher/extract_attribute_spec.rb +1 -5
  325. data/spec/mongoid/mongoizable_spec.rb +285 -0
  326. data/spec/mongoid/persistable/creatable_spec.rb +2 -2
  327. data/spec/mongoid/persistable/deletable_spec.rb +2 -2
  328. data/spec/mongoid/persistable/destroyable_spec.rb +2 -2
  329. data/spec/mongoid/persistable/upsertable_spec.rb +14 -0
  330. data/spec/mongoid/persistence_context_spec.rb +50 -1
  331. data/spec/mongoid/query_cache_middleware_spec.rb +0 -18
  332. data/spec/mongoid/query_cache_spec.rb +0 -154
  333. data/spec/mongoid/reloadable_spec.rb +35 -2
  334. data/spec/mongoid/scopable_spec.rb +54 -16
  335. data/spec/mongoid/shardable_spec.rb +14 -0
  336. data/spec/mongoid/stateful_spec.rb +28 -0
  337. data/spec/mongoid/timestamps_spec.rb +390 -0
  338. data/spec/mongoid/timestamps_spec_models.rb +67 -0
  339. data/spec/mongoid/touchable_spec.rb +116 -0
  340. data/spec/mongoid/touchable_spec_models.rb +12 -8
  341. data/spec/mongoid/traversable_spec.rb +4 -11
  342. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  343. data/spec/mongoid/validatable/uniqueness_spec.rb +59 -31
  344. data/spec/mongoid/warnings_spec.rb +35 -0
  345. data/spec/rails/controller_extension/controller_runtime_spec.rb +2 -2
  346. data/spec/rails/mongoid_spec.rb +4 -16
  347. data/spec/shared/lib/mrss/constraints.rb +8 -16
  348. data/spec/shared/lib/mrss/docker_runner.rb +23 -3
  349. data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
  350. data/spec/shared/lib/mrss/lite_constraints.rb +32 -1
  351. data/spec/shared/share/Dockerfile.erb +34 -48
  352. data/spec/shared/shlib/config.sh +27 -0
  353. data/spec/shared/shlib/server.sh +32 -19
  354. data/spec/shared/shlib/set_env.sh +37 -0
  355. data/spec/support/constraints.rb +24 -0
  356. data/spec/support/macros.rb +55 -0
  357. data/spec/support/models/augmentation.rb +12 -0
  358. data/spec/support/models/band.rb +3 -0
  359. data/spec/support/models/catalog.rb +24 -0
  360. data/spec/support/models/circus.rb +3 -0
  361. data/spec/support/models/code.rb +2 -0
  362. data/spec/support/models/fanatic.rb +8 -0
  363. data/spec/support/models/implant.rb +9 -0
  364. data/spec/support/models/label.rb +2 -0
  365. data/spec/support/models/membership.rb +1 -0
  366. data/spec/support/models/passport.rb +9 -0
  367. data/spec/support/models/person.rb +1 -0
  368. data/spec/support/models/player.rb +2 -0
  369. data/spec/support/models/powerup.rb +12 -0
  370. data/spec/support/models/registry.rb +1 -0
  371. data/spec/support/models/school.rb +14 -0
  372. data/spec/support/models/shield.rb +18 -0
  373. data/spec/support/models/student.rb +14 -0
  374. data/spec/support/models/weapon.rb +12 -0
  375. data/spec/support/schema_maps/schema_map_aws.json +17 -0
  376. data/spec/support/schema_maps/schema_map_aws_key_alt_names.json +12 -0
  377. data/spec/support/schema_maps/schema_map_azure.json +17 -0
  378. data/spec/support/schema_maps/schema_map_azure_key_alt_names.json +12 -0
  379. data/spec/support/schema_maps/schema_map_gcp.json +17 -0
  380. data/spec/support/schema_maps/schema_map_gcp_key_alt_names.json +12 -0
  381. data/spec/support/schema_maps/schema_map_kmip.json +17 -0
  382. data/spec/support/schema_maps/schema_map_kmip_key_alt_names.json +12 -0
  383. data/spec/support/schema_maps/schema_map_local.json +18 -0
  384. data/spec/support/schema_maps/schema_map_local_key_alt_names.json +12 -0
  385. data/spec/support/spec_config.rb +4 -0
  386. data.tar.gz.sig +0 -0
  387. metadata +682 -619
  388. metadata.gz.sig +0 -0
  389. data/lib/mongoid/errors/eager_load.rb +0 -23
  390. data/lib/mongoid/errors/invalid_value.rb +0 -17
  391. data/spec/mongoid/errors/eager_load_spec.rb +0 -31
@@ -24,6 +24,34 @@ describe 'embedded associations' do
24
24
  it 'performs dirty tracking efficiently' do
25
25
  subject.changed?.should be false
26
26
  end
27
+
28
+ it 'calculates the descendants properly' do
29
+ expect(subject._descendants.length).to eq(40)
30
+ end
31
+ end
32
+
33
+ context 'when association is cyclic and the _id is nil' do
34
+ before do
35
+ # create deeply nested record
36
+ a = EmmOuter.create(level: 0)
37
+ level = 1
38
+ iter = a.inners.create(id: nil, level: level)
39
+ loop do
40
+ iter.friends.create(id: nil, level: (level += 1))
41
+ iter = iter.friends[0]
42
+ break if level == 40
43
+ end
44
+ end
45
+
46
+ let(:subject) { EmmOuter.first }
47
+
48
+ it 'performs dirty tracking efficiently' do
49
+ subject.changed?.should be false
50
+ end
51
+
52
+ it 'calculates the descendants properly' do
53
+ expect(subject._descendants.length).to eq(40)
54
+ end
27
55
  end
28
56
  end
29
57
  end
@@ -265,4 +265,19 @@ describe 'embedded associations' do
265
265
  end
266
266
  end
267
267
  end
268
+
269
+ context "when summing properties on an embedded child" do
270
+ let(:user) { EmmUser.new }
271
+ before do
272
+ user.orders.build(amount: 200)
273
+ expect(user.orders.sum(:amount)).to eq(200)
274
+
275
+ user.orders.delete_all
276
+ user.orders.build(amount: 500)
277
+ end
278
+
279
+ it "the cache is cleared after deletion" do
280
+ expect(user.orders.sum(:amount)).to eq(500)
281
+ end
282
+ end
268
283
  end
@@ -172,8 +172,6 @@ describe 'embeds_many associations' do
172
172
  # Mongoid uses the new value of `x` in the $pullAll query,
173
173
  # which doesn't match the document that is in the database,
174
174
  # resulting in the empty array assignment not taking effect.
175
- pending 'MONGOID-5037'
176
-
177
175
  canvas.shapes.first.x = 1
178
176
  canvas.shapes = []
179
177
  canvas.save!
@@ -203,4 +201,19 @@ describe 'embeds_many associations' do
203
201
  end
204
202
  end
205
203
  end
204
+
205
+ context 'when an anonymous class defines an embeds_many association' do
206
+ let(:klass) do
207
+ Class.new do
208
+ include Mongoid::Document
209
+ embeds_many :addresses
210
+ end
211
+ end
212
+
213
+ it 'loads the association correctly' do
214
+ expect { klass }.to_not raise_error
215
+ expect { klass.new.addresses }.to_not raise_error
216
+ expect(klass.new.addresses.build).to be_a Address
217
+ end
218
+ end
206
219
  end
@@ -20,4 +20,22 @@ describe 'embeds_one associations' do
20
20
  end
21
21
  end
22
22
  end
23
+
24
+ context 'when an anonymous class defines an embeds_one association' do
25
+ let(:klass) do
26
+ Class.new do
27
+ include Mongoid::Document
28
+ embeds_one :address
29
+ end
30
+ end
31
+
32
+ it 'loads the association correctly' do
33
+ expect { klass }.to_not raise_error
34
+ expect { klass.new.address }.to_not raise_error
35
+ instance = klass.new
36
+ address = Address.new
37
+ instance.address = address
38
+ expect(instance.address).to eq address
39
+ end
40
+ end
23
41
  end
@@ -27,6 +27,15 @@ describe 'Association foreign key configuration' do
27
27
  expect(email.company.id).to eq(company.id)
28
28
  end
29
29
 
30
+ it "has the correct criteria" do
31
+ company = ForeignKeySpec::Company.create!(c: "3")
32
+ email = ForeignKeySpec::Email.create!(company: company)
33
+
34
+ criteria = ForeignKeySpec::Email.where(company: company)
35
+
36
+ expect(criteria.selector).to eq({ "c_ref" => "3" })
37
+ end
38
+
30
39
  context 'with default scope' do
31
40
  context 'using default scope' do
32
41
  it 'looks up child' do
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'has_and_belongs_to_many associations' do
6
+
7
+ context 'when an anonymous class defines a has_and_belongs_to_many association' do
8
+ let(:klass) do
9
+ Class.new do
10
+ include Mongoid::Document
11
+ has_and_belongs_to_many :movies, inverse_of: nil
12
+ end
13
+ end
14
+
15
+ it 'loads the association correctly' do
16
+ expect { klass }.to_not raise_error
17
+ expect { klass.new.movies }.to_not raise_error
18
+ expect(klass.new.movies.build).to be_a Movie
19
+ end
20
+ end
21
+ end
@@ -94,7 +94,7 @@ describe 'has_one associations' do
94
94
  context 'using send' do
95
95
  it 'delegates to the field' do
96
96
  if reloaded
97
- pending 'MONGOID-4018'
97
+ pending 'MONGOID-5018'
98
98
  end
99
99
 
100
100
  parent.accreditation.send(:format).should == 'fmt'
@@ -173,4 +173,100 @@ describe 'has_one associations' do
173
173
  end
174
174
  end
175
175
  end
176
+
177
+ context "when assigning to a has_one" do
178
+ let(:post) { HomPost.create! }
179
+ let(:comment1) { HomComment.create!(content: "Comment 1") }
180
+
181
+ context "when assigning the same value" do
182
+ let(:comment2) { HomComment.create! }
183
+
184
+ it "persists it correctly" do
185
+ post.comment = comment1
186
+ post.reload
187
+ expect(post.comment).to eq(comment1)
188
+
189
+ post.comment = comment1
190
+ post.reload
191
+ expect(post.comment).to eq(comment1)
192
+ end
193
+ end
194
+
195
+ context "when assigning two values with the same _id" do
196
+ let(:comment2) { HomComment.new(id: comment1.id) }
197
+
198
+ it "raises a duplicate key error" do
199
+ post.comment = comment1
200
+ expect do
201
+ post.comment = comment2
202
+ end.to raise_error(Mongo::Error::OperationFailure, /duplicate key/)
203
+ end
204
+ end
205
+
206
+ context "when duping the object and changing attributes" do
207
+ let(:comment2) { comment1.dup }
208
+
209
+ before do
210
+ comment2.content = "Comment 2"
211
+
212
+ post.comment = comment1
213
+ post.reload
214
+ end
215
+
216
+ it "updates the attributes correctly" do
217
+ post.comment = comment2
218
+ post.reload
219
+
220
+ expect(post.comment).to eq(comment2)
221
+ expect(post.comment.content).to eq(comment2.content)
222
+ end
223
+ end
224
+
225
+ context "when explicitly setting the foreign key" do
226
+ let(:comment2) { HomComment.new(post_id: post.id, content: "2") }
227
+
228
+ it "persists the new comment" do
229
+ post.comment = comment1
230
+ post.reload
231
+
232
+ post.comment = comment2
233
+ post.reload
234
+
235
+ expect(post.comment).to eq(comment2)
236
+ expect(post.comment.content).to eq(comment2.content)
237
+ end
238
+ end
239
+
240
+ context "when reassigning the same value" do
241
+ let(:comment2) { HomComment.create!(content: "Comment 2") }
242
+
243
+ it "persists it correctly" do
244
+ post.comment = comment1
245
+ post.reload
246
+ expect(post.comment).to eq(comment1)
247
+
248
+ post.comment = comment2
249
+ post.reload
250
+ expect(post.comment).to eq(comment2)
251
+
252
+ post.comment = comment1
253
+ post.reload
254
+ expect(post.comment).to eq(nil)
255
+ end
256
+ end
257
+ end
258
+
259
+ context "when overwriting an association" do
260
+ let(:post1) { HomPost.create!(title: "post 1") }
261
+ let(:post2) { HomPost.create!(title: "post 2") }
262
+ let(:comment) { HomComment.create(post: post1) }
263
+
264
+ it "does not overwrite the original value" do
265
+ pending "MONGOID-3999"
266
+ p1 = comment.post
267
+ expect(p1.title).to eq("post 1")
268
+ comment.post = post2
269
+ expect(p1.title).to eq("post 1")
270
+ end
271
+ end
176
272
  end
@@ -49,7 +49,7 @@ describe 'association :scope option' do
49
49
  it 'initially associates the documents in-memory' do
50
50
  expect(trainer1.animal).to eq animal2
51
51
  expect(trainer2.animal).to eq animal3
52
- expect(animal1.trainer).to eq trainer1
52
+ expect(animal1.trainer).to be_nil
53
53
  expect(animal2.trainer).to eq trainer1
54
54
  expect(animal3.trainer).to eq trainer2
55
55
  end
@@ -1,12 +1,17 @@
1
1
  class Galaxy
2
2
  include Mongoid::Document
3
+ include Mongoid::Timestamps
3
4
 
4
5
  field :age, type: Integer
5
-
6
+ field :was_touched, type: Mongoid::Boolean, default: false
6
7
  before_validation :set_age
7
8
 
8
9
  embeds_many :stars
9
10
 
11
+ set_callback(:touch, :before) do |document|
12
+ self.was_touched = true
13
+ end
14
+
10
15
  private
11
16
 
12
17
  def set_age
@@ -16,15 +21,21 @@ end
16
21
 
17
22
  class Star
18
23
  include Mongoid::Document
24
+ include Mongoid::Timestamps
19
25
 
20
26
  embedded_in :galaxy
21
27
 
22
28
  field :age, type: Integer
29
+ field :was_touched_after_parent, type: Mongoid::Boolean, default: false
23
30
 
24
31
  before_validation :set_age
25
32
 
26
33
  embeds_many :planets
27
34
 
35
+ set_callback(:touch, :before) do |document|
36
+ self.was_touched_after_parent = true if galaxy.was_touched
37
+ end
38
+
28
39
  private
29
40
 
30
41
  def set_age
@@ -34,13 +45,19 @@ end
34
45
 
35
46
  class Planet
36
47
  include Mongoid::Document
48
+ include Mongoid::Timestamps
37
49
 
38
50
  embedded_in :star
39
51
 
40
52
  field :age, type: Integer
53
+ field :was_touched_after_parent, type: Mongoid::Boolean, default: false
41
54
 
42
55
  before_validation :set_age
43
56
 
57
+ set_callback(:touch, :before) do |document|
58
+ self.was_touched_after_parent = true if star.was_touched_after_parent
59
+ end
60
+
44
61
  private
45
62
 
46
63
  def set_age
@@ -59,3 +76,80 @@ class Emission
59
76
 
60
77
  attr_reader :previous
61
78
  end
79
+
80
+ class Country
81
+ include Mongoid::Document
82
+
83
+ field :age
84
+
85
+ before_validation :set_age
86
+
87
+ embeds_one :president
88
+
89
+ private
90
+
91
+ def set_age
92
+ self.age ||= 245
93
+ end
94
+ end
95
+
96
+ class President
97
+ include Mongoid::Document
98
+
99
+ embedded_in :country
100
+
101
+ field :age
102
+
103
+ field :name
104
+
105
+ before_validation :set_age
106
+
107
+ embeds_one :first_spouse
108
+
109
+ private
110
+
111
+ def set_age
112
+ self.age ||= 79
113
+ end
114
+ end
115
+
116
+ class FirstSpouse
117
+ include Mongoid::Document
118
+
119
+ embedded_in :president
120
+
121
+ field :name
122
+ field :age, type: Integer
123
+
124
+ before_validation :set_age
125
+
126
+ private
127
+
128
+ def set_age
129
+ self.age ||= 70
130
+ end
131
+ end
132
+
133
+ class Architect
134
+ include Mongoid::Document
135
+
136
+ has_and_belongs_to_many :buildings, after_add: :after_add_callback,
137
+ after_remove: :after_remove_callback, dependent: :nullify
138
+
139
+ field :after_add_num_buildings, type: Integer
140
+ field :after_remove_num_buildings, type: Integer
141
+
142
+ def after_add_callback(obj)
143
+ self.after_add_num_buildings = self.buildings.length
144
+ end
145
+
146
+ def after_remove_callback(obj)
147
+ self.after_remove_num_buildings = self.buildings.length
148
+ end
149
+ end
150
+
151
+ class Building
152
+ include Mongoid::Document
153
+
154
+ has_and_belongs_to_many :architects, dependent: :nullify
155
+ end
@@ -188,8 +188,6 @@ describe 'callbacks integration tests' do
188
188
  end
189
189
 
190
190
  it 'persists the attribute value' do
191
- pending 'MONGOID-4476'
192
-
193
191
  Galaxy.find(instance.id).stars.first.planets.first.age.should == 2_000
194
192
  end
195
193
  end
@@ -211,18 +209,242 @@ describe 'callbacks integration tests' do
211
209
  end
212
210
  end
213
211
  end
212
+
213
+ context 'when updating top-level embeds_one document via #update_attributes!' do
214
+ let!(:instance) do
215
+ Country.create!
216
+ end
217
+
218
+ context 'embedded document' do
219
+ shared_examples 'persists the attribute value' do
220
+ it 'writes the attribute value into the model' do
221
+ instance.president.age.should == 79
222
+ end
223
+
224
+ it 'persists the attribute value' do
225
+ Country.find(instance.id).president.age.should == 79
226
+ end
227
+ end
228
+
229
+ context 'set as a document instance' do
230
+ before do
231
+ instance.update_attributes!(president: President.new)
232
+ end
233
+
234
+ include_examples 'persists the attribute value'
235
+ end
236
+
237
+ context 'set as attributes on parent' do
238
+ before do
239
+ instance.update_attributes!(president: { name: "Abraham Lincoln" })
240
+ end
241
+
242
+ include_examples 'persists the attribute value'
243
+ end
244
+ end
245
+
246
+ context 'nested embedded document' do
247
+ shared_examples 'persists the attribute value' do
248
+ it 'writes the attribute value into the model' do
249
+ instance.president.first_spouse.age.should == 70
250
+ end
251
+
252
+ it 'persists the attribute value' do
253
+ Country.find(instance.id).president.first_spouse.age.should == 70
254
+ end
255
+ end
256
+
257
+ context 'set as a document instance' do
258
+ before do
259
+ instance.update_attributes!(president: President.new(first_spouse: FirstSpouse.new))
260
+ end
261
+
262
+ include_examples 'persists the attribute value'
263
+ end
264
+
265
+ context 'set as attributes on parent' do
266
+ before do
267
+ instance.update_attributes!(president: { first_spouse: { name: "Mary Todd Lincoln" } })
268
+ end
269
+
270
+ include_examples 'persists the attribute value'
271
+ end
272
+ end
273
+ end
214
274
  end
215
275
 
216
276
  context 'attribute_was value in after_save callback' do
217
277
  let!(:obj) { Emission.create!(frequency: 1) }
218
278
 
219
279
  it 'is set to the new value' do
220
- pending 'MONGOID-5104'
221
-
222
280
  obj.frequency = 2
223
281
  obj.save!
224
282
 
225
283
  obj.previous.should == 2
226
284
  end
227
285
  end
286
+
287
+ context 'atomic_selector in after_save callback' do
288
+ let(:name) do
289
+ 'Alice'
290
+ end
291
+
292
+ let(:new_name) do
293
+ 'Bob'
294
+ end
295
+
296
+ class CBIntSpecProfile
297
+ include Mongoid::Document
298
+ field :name, type: String
299
+ shard_key :name
300
+
301
+ attr_reader :atomic_selector_in_after_save
302
+
303
+ after_save do |document|
304
+ @atomic_selector_in_after_save = document.atomic_selector
305
+ end
306
+ end
307
+
308
+ it 'has updated attributes' do
309
+ profile = CBIntSpecProfile.create!(name: name)
310
+ profile.name = new_name
311
+ profile.save!
312
+ expect(
313
+ profile.atomic_selector_in_after_save['name']
314
+ ).to eq(new_name)
315
+ end
316
+ end
317
+
318
+ context "When touching an embedded document" do
319
+ let(:planet) { Planet.new }
320
+ let(:star) { Star.new }
321
+ let(:galaxy) { Galaxy.create! }
322
+
323
+ before do
324
+ star.planets << planet
325
+ galaxy.stars << star
326
+ end
327
+
328
+ it "the parent document touch callback gets called before the child" do
329
+ planet.touch
330
+ expect(galaxy.was_touched).to be true
331
+ expect(star.was_touched_after_parent).to be true
332
+ expect(planet.was_touched_after_parent).to be true
333
+ end
334
+ end
335
+
336
+ context "when reloading has_and_belongs_to_many after_save and after_remove callbacks" do
337
+
338
+ let(:architect) { Architect.create }
339
+
340
+ let(:b1) { Building.create }
341
+
342
+ let(:b2) { Building.create }
343
+
344
+ let(:b3) { Building.create }
345
+
346
+ it "counts added/removed buildings correctly" do
347
+ architect.buildings << b1
348
+ expect(architect.after_add_num_buildings).to eq(1)
349
+
350
+ architect.reload
351
+ architect.buildings << b2
352
+ expect(architect.after_add_num_buildings).to eq(2)
353
+
354
+ architect.reload
355
+ architect.buildings << b3
356
+ expect(architect.after_add_num_buildings).to eq(3)
357
+
358
+ architect.reload
359
+ architect.buildings.delete(b3)
360
+ expect(architect.after_remove_num_buildings).to eq(2)
361
+ end
362
+ end
363
+
364
+ context '_previously was methods in after_save callback' do
365
+ let(:title) do
366
+ "Title"
367
+ end
368
+
369
+ let(:updated_title) do
370
+ "Updated title"
371
+ end
372
+
373
+ let(:age) do
374
+ 10
375
+ end
376
+
377
+ it do
378
+ class PreviouslyWasPerson
379
+ include Mongoid::Document
380
+
381
+ field :title, type: String
382
+ field :age, type: Integer
383
+
384
+ attr_reader :after_save_vals
385
+
386
+ set_callback :save, :after do |doc|
387
+ @after_save_vals ||= []
388
+ @after_save_vals << [doc.title_previously_was, doc.age_previously_was]
389
+ end
390
+ end
391
+
392
+ person = PreviouslyWasPerson.create!(title: title, age: age)
393
+ person.title = updated_title
394
+ person.save!
395
+ expect(person.after_save_vals).to eq([
396
+ # Field values are nil before create
397
+ [nil, nil],
398
+ [title, age]
399
+ ])
400
+ end
401
+ end
402
+
403
+ context 'previously_new_record? in after_save' do
404
+ it do
405
+ class PreviouslyNewRecordPerson
406
+ include Mongoid::Document
407
+
408
+ field :title, type: String
409
+ field :age, type: Integer
410
+
411
+ attr_reader :previously_new_record_value
412
+
413
+ set_callback :save, :after do |doc|
414
+ @previously_new_record_value = doc.previously_new_record?
415
+ end
416
+ end
417
+
418
+ person = PreviouslyNewRecordPerson.create!(title: "title", age: 55)
419
+ expect(person.previously_new_record_value).to be_truthy
420
+ person.title = "New title"
421
+ person.save!
422
+ expect(person.previously_new_record_value).to be_falsey
423
+ end
424
+ end
425
+
426
+ context 'previously_persisted? in after_destroy' do
427
+ it do
428
+ class PreviouslyPersistedPerson
429
+ include Mongoid::Document
430
+
431
+ field :title, type: String
432
+ field :age, type: Integer
433
+
434
+ attr_reader :previously_persisted_value
435
+
436
+ set_callback :destroy, :after do |doc|
437
+ @previously_persisted_value = doc.previously_persisted?
438
+ end
439
+ end
440
+
441
+ unsaved_person = PreviouslyPersistedPerson.new(title: "title", age: 55)
442
+ unsaved_person.destroy
443
+ expect(unsaved_person.previously_persisted_value).to be_falsey
444
+
445
+ saved_person = PreviouslyPersistedPerson.create(title: "title", age: 55)
446
+ saved_person.destroy
447
+ expect(saved_person.previously_persisted_value).to be_truthy
448
+ end
449
+ end
228
450
  end