mongoid 3.1.5 → 8.0.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 (1501) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +636 -33
  4. data/LICENSE +2 -1
  5. data/README.md +32 -24
  6. data/Rakefile +75 -5
  7. data/lib/config/locales/en.yml +301 -132
  8. data/lib/mongoid/association/accessors.rb +431 -0
  9. data/lib/mongoid/association/bindable.rb +227 -0
  10. data/lib/mongoid/association/builders.rb +86 -0
  11. data/lib/mongoid/association/constrainable.rb +42 -0
  12. data/lib/mongoid/association/depending.rb +128 -0
  13. data/lib/mongoid/association/eager_loadable.rb +57 -0
  14. data/lib/mongoid/association/embedded/batchable.rb +398 -0
  15. data/lib/mongoid/association/embedded/cyclic.rb +102 -0
  16. data/lib/mongoid/association/embedded/embedded_in/binding.rb +74 -0
  17. data/lib/mongoid/association/embedded/embedded_in/buildable.rb +38 -0
  18. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +111 -0
  19. data/lib/mongoid/association/embedded/embedded_in.rb +135 -0
  20. data/lib/mongoid/association/embedded/embeds_many/binding.rb +42 -0
  21. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +45 -0
  22. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +571 -0
  23. data/lib/mongoid/association/embedded/embeds_many.rb +183 -0
  24. data/lib/mongoid/association/embedded/embeds_one/binding.rb +43 -0
  25. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +53 -0
  26. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +164 -0
  27. data/lib/mongoid/association/embedded/embeds_one.rb +150 -0
  28. data/lib/mongoid/association/embedded.rb +6 -0
  29. data/lib/mongoid/association/macros.rb +228 -0
  30. data/lib/mongoid/association/many.rb +202 -0
  31. data/lib/mongoid/association/marshalable.rb +31 -0
  32. data/lib/mongoid/association/nested/many.rb +192 -0
  33. data/lib/mongoid/association/nested/nested_buildable.rb +66 -0
  34. data/lib/mongoid/association/nested/one.rb +116 -0
  35. data/lib/mongoid/association/nested.rb +15 -0
  36. data/lib/mongoid/association/one.rb +53 -0
  37. data/lib/mongoid/association/options.rb +122 -0
  38. data/lib/mongoid/association/proxy.rb +200 -0
  39. data/lib/mongoid/association/referenced/auto_save.rb +74 -0
  40. data/lib/mongoid/association/referenced/belongs_to/binding.rb +83 -0
  41. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +48 -0
  42. data/lib/mongoid/association/referenced/belongs_to/eager.rb +73 -0
  43. data/lib/mongoid/association/referenced/belongs_to/proxy.rb +124 -0
  44. data/lib/mongoid/association/referenced/belongs_to.rb +226 -0
  45. data/lib/mongoid/association/referenced/counter_cache.rb +152 -0
  46. data/lib/mongoid/association/referenced/eager.rb +163 -0
  47. data/lib/mongoid/association/referenced/has_and_belongs_to_many/binding.rb +72 -0
  48. data/lib/mongoid/association/referenced/has_and_belongs_to_many/buildable.rb +40 -0
  49. data/lib/mongoid/association/referenced/has_and_belongs_to_many/eager.rb +53 -0
  50. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +345 -0
  51. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +273 -0
  52. data/lib/mongoid/association/referenced/has_many/binding.rb +36 -0
  53. data/lib/mongoid/association/referenced/has_many/buildable.rb +38 -0
  54. data/lib/mongoid/association/referenced/has_many/eager.rb +44 -0
  55. data/lib/mongoid/association/referenced/has_many/enumerable.rb +494 -0
  56. data/lib/mongoid/association/referenced/has_many/proxy.rb +551 -0
  57. data/lib/mongoid/association/referenced/has_many.rb +251 -0
  58. data/lib/mongoid/association/referenced/has_one/binding.rb +42 -0
  59. data/lib/mongoid/association/referenced/has_one/buildable.rb +74 -0
  60. data/lib/mongoid/association/referenced/has_one/eager.rb +36 -0
  61. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +113 -0
  62. data/lib/mongoid/association/referenced/has_one/proxy.rb +108 -0
  63. data/lib/mongoid/association/referenced/has_one.rb +184 -0
  64. data/lib/mongoid/association/referenced/syncable.rb +155 -0
  65. data/lib/mongoid/association/referenced.rb +9 -0
  66. data/lib/mongoid/association/reflections.rb +69 -0
  67. data/lib/mongoid/association/relatable.rb +489 -0
  68. data/lib/mongoid/association.rb +135 -0
  69. data/lib/mongoid/atomic/modifiers.rb +41 -61
  70. data/lib/mongoid/atomic/paths/embedded/many.rb +24 -8
  71. data/lib/mongoid/atomic/paths/embedded/one.rb +5 -8
  72. data/lib/mongoid/atomic/paths/embedded.rb +3 -34
  73. data/lib/mongoid/atomic/paths/root.rb +4 -20
  74. data/lib/mongoid/atomic/paths.rb +2 -1
  75. data/lib/mongoid/atomic.rb +52 -69
  76. data/lib/mongoid/attributes/dynamic.rb +141 -0
  77. data/lib/mongoid/attributes/nested.rb +93 -0
  78. data/lib/mongoid/attributes/processing.rb +35 -97
  79. data/lib/mongoid/attributes/projector.rb +119 -0
  80. data/lib/mongoid/attributes/readonly.rb +27 -10
  81. data/lib/mongoid/attributes.rb +159 -181
  82. data/lib/mongoid/cacheable.rb +33 -0
  83. data/lib/mongoid/changeable.rb +420 -0
  84. data/lib/mongoid/clients/factory.rb +105 -0
  85. data/lib/mongoid/clients/options.rb +111 -0
  86. data/lib/mongoid/clients/sessions.rb +113 -0
  87. data/lib/mongoid/clients/storage_options.rb +79 -0
  88. data/lib/mongoid/clients/validators/storage.rb +58 -0
  89. data/lib/mongoid/clients/validators.rb +3 -0
  90. data/lib/mongoid/clients.rb +79 -0
  91. data/lib/mongoid/composable.rb +128 -0
  92. data/lib/mongoid/config/environment.rb +51 -13
  93. data/lib/mongoid/config/options.rb +30 -18
  94. data/lib/mongoid/config/validators/client.rb +128 -0
  95. data/lib/mongoid/config/validators/option.rb +3 -4
  96. data/lib/mongoid/config/validators.rb +3 -2
  97. data/lib/mongoid/config.rb +170 -89
  98. data/lib/mongoid/contextual/aggregable/memory.rb +40 -27
  99. data/lib/mongoid/contextual/aggregable/mongo.rb +33 -36
  100. data/lib/mongoid/contextual/aggregable/none.rb +65 -0
  101. data/lib/mongoid/contextual/aggregable.rb +17 -0
  102. data/lib/mongoid/contextual/atomic.rb +80 -79
  103. data/lib/mongoid/contextual/command.rb +8 -11
  104. data/lib/mongoid/contextual/geo_near.rb +42 -44
  105. data/lib/mongoid/contextual/map_reduce.rb +33 -127
  106. data/lib/mongoid/contextual/memory.rb +226 -88
  107. data/lib/mongoid/contextual/mongo.rb +466 -293
  108. data/lib/mongoid/contextual/none.rb +193 -0
  109. data/lib/mongoid/contextual/queryable.rb +3 -4
  110. data/lib/mongoid/contextual.rb +11 -11
  111. data/lib/mongoid/copyable.rb +68 -20
  112. data/lib/mongoid/criteria/findable.rb +143 -0
  113. data/lib/mongoid/criteria/includable.rb +92 -0
  114. data/lib/mongoid/criteria/inspectable.rb +24 -0
  115. data/lib/mongoid/criteria/marshalable.rb +55 -0
  116. data/lib/mongoid/criteria/modifiable.rb +235 -0
  117. data/lib/mongoid/criteria/options.rb +24 -0
  118. data/lib/mongoid/criteria/permission.rb +71 -0
  119. data/lib/mongoid/criteria/queryable/aggregable.rb +109 -0
  120. data/lib/mongoid/criteria/queryable/expandable.rb +68 -0
  121. data/lib/mongoid/criteria/queryable/extensions/array.rb +151 -0
  122. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +57 -0
  123. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +33 -0
  124. data/lib/mongoid/criteria/queryable/extensions/date.rb +63 -0
  125. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +52 -0
  126. data/lib/mongoid/criteria/queryable/extensions/hash.rb +163 -0
  127. data/lib/mongoid/criteria/queryable/extensions/nil_class.rb +75 -0
  128. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +81 -0
  129. data/lib/mongoid/criteria/queryable/extensions/object.rb +182 -0
  130. data/lib/mongoid/criteria/queryable/extensions/range.rb +102 -0
  131. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +72 -0
  132. data/lib/mongoid/criteria/queryable/extensions/set.rb +33 -0
  133. data/lib/mongoid/criteria/queryable/extensions/string.rb +122 -0
  134. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +74 -0
  135. data/lib/mongoid/criteria/queryable/extensions/time.rb +60 -0
  136. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +66 -0
  137. data/lib/mongoid/criteria/queryable/extensions.rb +25 -0
  138. data/lib/mongoid/criteria/queryable/key.rb +177 -0
  139. data/lib/mongoid/criteria/queryable/macroable.rb +26 -0
  140. data/lib/mongoid/criteria/queryable/mergeable.rb +434 -0
  141. data/lib/mongoid/criteria/queryable/optional.rb +380 -0
  142. data/lib/mongoid/criteria/queryable/options.rb +136 -0
  143. data/lib/mongoid/criteria/queryable/pipeline.rb +106 -0
  144. data/lib/mongoid/criteria/queryable/selectable.rb +937 -0
  145. data/lib/mongoid/criteria/queryable/selector.rb +287 -0
  146. data/lib/mongoid/criteria/queryable/smash.rb +128 -0
  147. data/lib/mongoid/criteria/queryable/storable.rb +237 -0
  148. data/lib/mongoid/criteria/queryable.rb +90 -0
  149. data/lib/mongoid/criteria/scopable.rb +166 -0
  150. data/lib/mongoid/criteria.rb +177 -189
  151. data/lib/mongoid/deprecable.rb +36 -0
  152. data/lib/mongoid/deprecation.rb +25 -0
  153. data/lib/mongoid/document.rb +193 -139
  154. data/lib/mongoid/equality.rb +35 -18
  155. data/lib/mongoid/errors/ambiguous_relationship.rb +5 -6
  156. data/lib/mongoid/errors/callback.rb +2 -3
  157. data/lib/mongoid/errors/criteria_argument_required.rb +18 -0
  158. data/lib/mongoid/errors/delete_restriction.rb +10 -13
  159. data/lib/mongoid/errors/document_not_destroyed.rb +22 -0
  160. data/lib/mongoid/errors/document_not_found.rb +36 -21
  161. data/lib/mongoid/errors/empty_config_file.rb +25 -0
  162. data/lib/mongoid/errors/in_memory_collation_not_supported.rb +19 -0
  163. data/lib/mongoid/errors/invalid_collection.rb +2 -1
  164. data/lib/mongoid/errors/invalid_config_file.rb +25 -0
  165. data/lib/mongoid/errors/invalid_config_option.rb +3 -4
  166. data/lib/mongoid/errors/invalid_dependent_strategy.rb +31 -0
  167. data/lib/mongoid/errors/invalid_discriminator_key_target.rb +24 -0
  168. data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +23 -0
  169. data/lib/mongoid/errors/invalid_elem_match_operator.rb +32 -0
  170. data/lib/mongoid/errors/invalid_estimated_count_criteria.rb +25 -0
  171. data/lib/mongoid/errors/invalid_expression_operator.rb +27 -0
  172. data/lib/mongoid/errors/invalid_field.rb +10 -9
  173. data/lib/mongoid/errors/invalid_field_operator.rb +32 -0
  174. data/lib/mongoid/errors/invalid_field_option.rb +2 -3
  175. data/lib/mongoid/errors/invalid_field_type.rb +26 -0
  176. data/lib/mongoid/errors/invalid_find.rb +2 -3
  177. data/lib/mongoid/errors/invalid_includes.rb +2 -3
  178. data/lib/mongoid/errors/invalid_index.rb +2 -3
  179. data/lib/mongoid/errors/invalid_options.rb +4 -5
  180. data/lib/mongoid/errors/invalid_path.rb +2 -3
  181. data/lib/mongoid/errors/invalid_persistence_option.rb +26 -0
  182. data/lib/mongoid/errors/invalid_query.rb +40 -0
  183. data/lib/mongoid/errors/invalid_relation.rb +61 -0
  184. data/lib/mongoid/errors/invalid_relation_option.rb +28 -0
  185. data/lib/mongoid/errors/invalid_scope.rb +2 -3
  186. data/lib/mongoid/errors/invalid_session_use.rb +21 -0
  187. data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +6 -5
  188. data/lib/mongoid/errors/invalid_storage_options.rb +4 -5
  189. data/lib/mongoid/errors/invalid_storage_parent.rb +25 -0
  190. data/lib/mongoid/errors/invalid_time.rb +2 -3
  191. data/lib/mongoid/errors/inverse_not_found.rb +4 -5
  192. data/lib/mongoid/errors/mixed_client_configuration.rb +27 -0
  193. data/lib/mongoid/errors/mixed_relations.rb +2 -3
  194. data/lib/mongoid/errors/mongoid_error.rb +22 -23
  195. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +3 -4
  196. data/lib/mongoid/errors/no_client_config.rb +21 -0
  197. data/lib/mongoid/errors/no_client_database.rb +26 -0
  198. data/lib/mongoid/errors/no_client_hosts.rb +26 -0
  199. data/lib/mongoid/errors/no_clients_config.rb +19 -0
  200. data/lib/mongoid/errors/no_default_client.rb +22 -0
  201. data/lib/mongoid/errors/no_environment.rb +2 -3
  202. data/lib/mongoid/errors/no_map_reduce_output.rb +2 -3
  203. data/lib/mongoid/errors/no_metadata.rb +2 -3
  204. data/lib/mongoid/errors/no_parent.rb +2 -3
  205. data/lib/mongoid/errors/readonly_attribute.rb +3 -4
  206. data/lib/mongoid/errors/readonly_document.rb +21 -0
  207. data/lib/mongoid/errors/scope_overwrite.rb +2 -1
  208. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +3 -1
  209. data/lib/mongoid/errors/unknown_attribute.rb +3 -4
  210. data/lib/mongoid/errors/unknown_model.rb +24 -0
  211. data/lib/mongoid/errors/unsaved_document.rb +3 -2
  212. data/lib/mongoid/errors/unsupported_javascript.rb +2 -3
  213. data/lib/mongoid/errors/validations.rb +2 -1
  214. data/lib/mongoid/errors.rb +30 -9
  215. data/lib/mongoid/evolvable.rb +4 -5
  216. data/lib/mongoid/extensions/array.rb +45 -52
  217. data/lib/mongoid/extensions/big_decimal.rb +41 -22
  218. data/lib/mongoid/extensions/binary.rb +42 -0
  219. data/lib/mongoid/extensions/boolean.rb +19 -17
  220. data/lib/mongoid/extensions/date.rb +33 -23
  221. data/lib/mongoid/extensions/date_time.rb +5 -13
  222. data/lib/mongoid/extensions/decimal128.rb +36 -0
  223. data/lib/mongoid/extensions/false_class.rb +5 -8
  224. data/lib/mongoid/extensions/float.rb +11 -16
  225. data/lib/mongoid/extensions/hash.rb +88 -49
  226. data/lib/mongoid/extensions/integer.rb +10 -18
  227. data/lib/mongoid/extensions/module.rb +3 -4
  228. data/lib/mongoid/extensions/nil_class.rb +2 -5
  229. data/lib/mongoid/extensions/object.rb +38 -62
  230. data/lib/mongoid/extensions/object_id.rb +7 -12
  231. data/lib/mongoid/extensions/range.rb +46 -17
  232. data/lib/mongoid/extensions/regexp.rb +15 -8
  233. data/lib/mongoid/extensions/set.rb +17 -15
  234. data/lib/mongoid/extensions/string.rb +40 -80
  235. data/lib/mongoid/extensions/symbol.rb +7 -23
  236. data/lib/mongoid/extensions/time.rb +42 -25
  237. data/lib/mongoid/extensions/time_with_zone.rb +27 -10
  238. data/lib/mongoid/extensions/true_class.rb +5 -8
  239. data/lib/mongoid/extensions.rb +31 -13
  240. data/lib/mongoid/factory.rb +99 -11
  241. data/lib/mongoid/fields/foreign_key.rb +26 -34
  242. data/lib/mongoid/fields/localized.rb +24 -13
  243. data/lib/mongoid/fields/standard.rb +19 -73
  244. data/lib/mongoid/fields/validators/macro.rb +56 -15
  245. data/lib/mongoid/fields/validators.rb +2 -1
  246. data/lib/mongoid/fields.rb +342 -87
  247. data/lib/mongoid/findable.rb +219 -0
  248. data/lib/mongoid/indexable/specification.rb +103 -0
  249. data/lib/mongoid/indexable/validators/options.rb +110 -0
  250. data/lib/mongoid/indexable.rb +148 -0
  251. data/lib/mongoid/inspectable.rb +52 -0
  252. data/lib/mongoid/interceptable.rb +312 -0
  253. data/lib/mongoid/loggable.rb +15 -18
  254. data/lib/mongoid/matchable.rb +23 -0
  255. data/lib/mongoid/matcher/all.rb +22 -0
  256. data/lib/mongoid/matcher/and.rb +21 -0
  257. data/lib/mongoid/matcher/bits.rb +41 -0
  258. data/lib/mongoid/matcher/bits_all_clear.rb +20 -0
  259. data/lib/mongoid/matcher/bits_all_set.rb +20 -0
  260. data/lib/mongoid/matcher/bits_any_clear.rb +20 -0
  261. data/lib/mongoid/matcher/bits_any_set.rb +20 -0
  262. data/lib/mongoid/matcher/elem_match.rb +36 -0
  263. data/lib/mongoid/matcher/elem_match_expression.rb +20 -0
  264. data/lib/mongoid/matcher/eq.rb +11 -0
  265. data/lib/mongoid/matcher/eq_impl.rb +67 -0
  266. data/lib/mongoid/matcher/eq_impl_with_regexp.rb +26 -0
  267. data/lib/mongoid/matcher/exists.rb +15 -0
  268. data/lib/mongoid/matcher/expression.rb +35 -0
  269. data/lib/mongoid/matcher/expression_operator.rb +19 -0
  270. data/lib/mongoid/matcher/field_expression.rb +62 -0
  271. data/lib/mongoid/matcher/field_operator.rb +54 -0
  272. data/lib/mongoid/matcher/gt.rb +17 -0
  273. data/lib/mongoid/matcher/gte.rb +17 -0
  274. data/lib/mongoid/matcher/in.rb +25 -0
  275. data/lib/mongoid/matcher/lt.rb +17 -0
  276. data/lib/mongoid/matcher/lte.rb +17 -0
  277. data/lib/mongoid/matcher/mod.rb +17 -0
  278. data/lib/mongoid/matcher/ne.rb +16 -0
  279. data/lib/mongoid/matcher/nin.rb +11 -0
  280. data/lib/mongoid/matcher/nor.rb +25 -0
  281. data/lib/mongoid/matcher/not.rb +29 -0
  282. data/lib/mongoid/matcher/or.rb +21 -0
  283. data/lib/mongoid/matcher/regex.rb +41 -0
  284. data/lib/mongoid/matcher/size.rb +26 -0
  285. data/lib/mongoid/matcher/type.rb +99 -0
  286. data/lib/mongoid/matcher.rb +115 -0
  287. data/lib/mongoid/persistable/creatable.rb +181 -0
  288. data/lib/mongoid/persistable/deletable.rb +132 -0
  289. data/lib/mongoid/persistable/destroyable.rb +57 -0
  290. data/lib/mongoid/persistable/incrementable.rb +35 -0
  291. data/lib/mongoid/persistable/logical.rb +36 -0
  292. data/lib/mongoid/persistable/poppable.rb +36 -0
  293. data/lib/mongoid/persistable/pullable.rb +50 -0
  294. data/lib/mongoid/persistable/pushable.rb +66 -0
  295. data/lib/mongoid/persistable/renamable.rb +37 -0
  296. data/lib/mongoid/persistable/savable.rb +47 -0
  297. data/lib/mongoid/persistable/settable.rb +93 -0
  298. data/lib/mongoid/persistable/unsettable.rb +36 -0
  299. data/lib/mongoid/persistable/updatable.rb +165 -0
  300. data/lib/mongoid/persistable/upsertable.rb +51 -0
  301. data/lib/mongoid/persistable.rb +305 -0
  302. data/lib/mongoid/persistence_context.rb +239 -0
  303. data/lib/mongoid/positional.rb +72 -0
  304. data/lib/mongoid/query_cache.rb +64 -0
  305. data/lib/mongoid/railtie.rb +35 -78
  306. data/lib/mongoid/railties/controller_runtime.rb +88 -0
  307. data/lib/mongoid/railties/database.rake +18 -25
  308. data/lib/mongoid/reloadable.rb +94 -0
  309. data/lib/mongoid/scopable.rb +324 -0
  310. data/lib/mongoid/selectable.rb +49 -0
  311. data/lib/mongoid/serializable.rb +170 -0
  312. data/lib/mongoid/shardable.rb +130 -0
  313. data/lib/mongoid/stateful.rb +134 -0
  314. data/lib/mongoid/stringified_symbol.rb +52 -0
  315. data/lib/mongoid/tasks/database.rake +38 -0
  316. data/lib/mongoid/tasks/database.rb +194 -0
  317. data/lib/mongoid/threaded/lifecycle.rb +28 -70
  318. data/lib/mongoid/threaded.rb +142 -219
  319. data/lib/mongoid/timestamps/created/short.rb +2 -1
  320. data/lib/mongoid/timestamps/created.rb +9 -5
  321. data/lib/mongoid/timestamps/short.rb +2 -1
  322. data/lib/mongoid/timestamps/timeless.rb +52 -16
  323. data/lib/mongoid/timestamps/updated/short.rb +4 -3
  324. data/lib/mongoid/timestamps/updated.rb +14 -9
  325. data/lib/mongoid/timestamps.rb +4 -3
  326. data/lib/mongoid/touchable.rb +131 -0
  327. data/lib/mongoid/traversable.rb +337 -0
  328. data/lib/mongoid/validatable/associated.rb +47 -0
  329. data/lib/mongoid/validatable/format.rb +21 -0
  330. data/lib/mongoid/validatable/length.rb +21 -0
  331. data/lib/mongoid/validatable/localizable.rb +29 -0
  332. data/lib/mongoid/validatable/macros.rb +89 -0
  333. data/lib/mongoid/validatable/presence.rb +81 -0
  334. data/lib/mongoid/validatable/queryable.rb +29 -0
  335. data/lib/mongoid/validatable/uniqueness.rb +304 -0
  336. data/lib/mongoid/validatable.rb +160 -0
  337. data/lib/mongoid/version.rb +3 -2
  338. data/lib/mongoid/warnings.rb +28 -0
  339. data/lib/mongoid.rb +68 -109
  340. data/lib/rails/generators/mongoid/config/config_generator.rb +10 -2
  341. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +150 -45
  342. data/lib/rails/generators/mongoid/model/model_generator.rb +3 -3
  343. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +1 -4
  344. data/lib/rails/generators/mongoid_generator.rb +5 -41
  345. data/lib/rails/mongoid.rb +6 -129
  346. data/spec/README.md +33 -0
  347. data/spec/config/mongoid.yml +56 -25
  348. data/spec/config/mongoid_with_schema_map_uuid.yml +27 -0
  349. data/spec/integration/app_spec.rb +345 -0
  350. data/spec/integration/associations/belongs_to_spec.rb +33 -0
  351. data/spec/integration/associations/embedded_dirty_spec.rb +57 -0
  352. data/spec/integration/associations/embedded_spec.rb +283 -0
  353. data/spec/integration/associations/embeds_many_spec.rb +219 -0
  354. data/spec/integration/associations/embeds_one_spec.rb +41 -0
  355. data/spec/integration/associations/foreign_key_spec.rb +107 -0
  356. data/spec/integration/associations/foreign_key_spec_models.rb +64 -0
  357. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +21 -0
  358. data/spec/integration/associations/has_many_spec.rb +128 -0
  359. data/spec/integration/associations/has_one_spec.rb +272 -0
  360. data/spec/integration/associations/nested_attributes_assignment_spec.rb +115 -0
  361. data/spec/integration/associations/reverse_population_spec.rb +34 -0
  362. data/spec/integration/associations/reverse_population_spec_models.rb +36 -0
  363. data/spec/integration/associations/scope_option_spec.rb +101 -0
  364. data/spec/integration/atomic/modifiers_spec.rb +116 -0
  365. data/spec/integration/bson_regexp_raw_spec.rb +19 -0
  366. data/spec/integration/callbacks_models.rb +155 -0
  367. data/spec/integration/callbacks_spec.rb +450 -0
  368. data/spec/integration/contextual/empty_spec.rb +141 -0
  369. data/spec/integration/criteria/alias_query_spec.rb +161 -0
  370. data/spec/integration/criteria/date_field_spec.rb +40 -0
  371. data/spec/integration/criteria/default_scope_spec.rb +72 -0
  372. data/spec/integration/criteria/logical_spec.rb +124 -0
  373. data/spec/integration/criteria/range_spec.rb +359 -0
  374. data/spec/integration/criteria/time_with_zone_spec.rb +142 -0
  375. data/spec/integration/discriminator_key_spec.rb +392 -0
  376. data/spec/integration/discriminator_value_spec.rb +206 -0
  377. data/spec/integration/document_spec.rb +51 -0
  378. data/spec/integration/dots_and_dollars_spec.rb +277 -0
  379. data/spec/integration/i18n_fallbacks_spec.rb +89 -0
  380. data/spec/integration/matcher_examples_spec.rb +765 -0
  381. data/spec/integration/matcher_operator_data/all.yml +140 -0
  382. data/spec/integration/matcher_operator_data/and.yml +93 -0
  383. data/spec/integration/matcher_operator_data/bits_all_clear.yml +159 -0
  384. data/spec/integration/matcher_operator_data/bits_all_set.yml +159 -0
  385. data/spec/integration/matcher_operator_data/bits_any_clear.yml +159 -0
  386. data/spec/integration/matcher_operator_data/bits_any_set.yml +159 -0
  387. data/spec/integration/matcher_operator_data/comment.yml +22 -0
  388. data/spec/integration/matcher_operator_data/elem_match.yml +409 -0
  389. data/spec/integration/matcher_operator_data/elem_match_expr.yml +213 -0
  390. data/spec/integration/matcher_operator_data/eq.yml +191 -0
  391. data/spec/integration/matcher_operator_data/exists.yml +213 -0
  392. data/spec/integration/matcher_operator_data/generic_op.yml +17 -0
  393. data/spec/integration/matcher_operator_data/gt.yml +132 -0
  394. data/spec/integration/matcher_operator_data/gt_types.yml +63 -0
  395. data/spec/integration/matcher_operator_data/gte.yml +132 -0
  396. data/spec/integration/matcher_operator_data/gte_types.yml +15 -0
  397. data/spec/integration/matcher_operator_data/implicit.yml +331 -0
  398. data/spec/integration/matcher_operator_data/implicit_traversal.yml +112 -0
  399. data/spec/integration/matcher_operator_data/in.yml +210 -0
  400. data/spec/integration/matcher_operator_data/invalid_op.yml +59 -0
  401. data/spec/integration/matcher_operator_data/invalid_syntax.yml +39 -0
  402. data/spec/integration/matcher_operator_data/lt.yml +132 -0
  403. data/spec/integration/matcher_operator_data/lt_types.yml +15 -0
  404. data/spec/integration/matcher_operator_data/lte.yml +132 -0
  405. data/spec/integration/matcher_operator_data/lte_types.yml +15 -0
  406. data/spec/integration/matcher_operator_data/mod.yml +55 -0
  407. data/spec/integration/matcher_operator_data/multiple.yml +29 -0
  408. data/spec/integration/matcher_operator_data/ne.yml +150 -0
  409. data/spec/integration/matcher_operator_data/ne_types.yml +15 -0
  410. data/spec/integration/matcher_operator_data/nin.yml +114 -0
  411. data/spec/integration/matcher_operator_data/nor.yml +126 -0
  412. data/spec/integration/matcher_operator_data/not.yml +196 -0
  413. data/spec/integration/matcher_operator_data/or.yml +137 -0
  414. data/spec/integration/matcher_operator_data/regex.yml +174 -0
  415. data/spec/integration/matcher_operator_data/regex_options.yml +72 -0
  416. data/spec/integration/matcher_operator_data/size.yml +174 -0
  417. data/spec/integration/matcher_operator_data/type.yml +70 -0
  418. data/spec/integration/matcher_operator_data/type_array.yml +16 -0
  419. data/spec/integration/matcher_operator_data/type_binary.yml +18 -0
  420. data/spec/integration/matcher_operator_data/type_boolean.yml +39 -0
  421. data/spec/integration/matcher_operator_data/type_code.yml +26 -0
  422. data/spec/integration/matcher_operator_data/type_code_with_scope.yml +26 -0
  423. data/spec/integration/matcher_operator_data/type_date.yml +39 -0
  424. data/spec/integration/matcher_operator_data/type_db_pointer.yml +19 -0
  425. data/spec/integration/matcher_operator_data/type_decimal.yml +41 -0
  426. data/spec/integration/matcher_operator_data/type_double.yml +15 -0
  427. data/spec/integration/matcher_operator_data/type_int32.yml +33 -0
  428. data/spec/integration/matcher_operator_data/type_int64.yml +33 -0
  429. data/spec/integration/matcher_operator_data/type_max_key.yml +17 -0
  430. data/spec/integration/matcher_operator_data/type_min_key.yml +17 -0
  431. data/spec/integration/matcher_operator_data/type_null.yml +23 -0
  432. data/spec/integration/matcher_operator_data/type_object.yml +23 -0
  433. data/spec/integration/matcher_operator_data/type_object_id.yml +25 -0
  434. data/spec/integration/matcher_operator_data/type_regex.yml +44 -0
  435. data/spec/integration/matcher_operator_data/type_string.yml +15 -0
  436. data/spec/integration/matcher_operator_data/type_symbol.yml +32 -0
  437. data/spec/integration/matcher_operator_data/type_timestamp.yml +25 -0
  438. data/spec/integration/matcher_operator_data/type_undefined.yml +17 -0
  439. data/spec/integration/matcher_operator_spec.rb +122 -0
  440. data/spec/integration/matcher_spec.rb +283 -0
  441. data/spec/integration/persistence/range_field_spec.rb +350 -0
  442. data/spec/integration/server_query_spec.rb +141 -0
  443. data/spec/integration/shardable_spec.rb +148 -0
  444. data/spec/integration/stringified_symbol_field_spec.rb +203 -0
  445. data/spec/lite_spec_helper.rb +83 -0
  446. data/spec/mongoid/association/accessors_spec.rb +1067 -0
  447. data/spec/mongoid/association/auto_save_spec.rb +403 -0
  448. data/spec/mongoid/association/builders_spec.rb +255 -0
  449. data/spec/mongoid/association/constrainable_spec.rb +117 -0
  450. data/spec/mongoid/association/counter_cache_spec.rb +452 -0
  451. data/spec/mongoid/association/depending_spec.rb +959 -0
  452. data/spec/mongoid/association/eager_spec.rb +282 -0
  453. data/spec/mongoid/association/embedded/cyclic_spec.rb +180 -0
  454. data/spec/mongoid/association/embedded/dirty_spec.rb +67 -0
  455. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +174 -0
  456. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +90 -0
  457. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +619 -0
  458. data/spec/mongoid/association/embedded/embedded_in_spec.rb +903 -0
  459. data/spec/mongoid/association/embedded/embeds_many/binding_spec.rb +56 -0
  460. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +218 -0
  461. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +4863 -0
  462. data/spec/mongoid/association/embedded/embeds_many_models.rb +226 -0
  463. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +63 -0
  464. data/spec/mongoid/association/embedded/embeds_many_spec.rb +932 -0
  465. data/spec/mongoid/association/embedded/embeds_one/binding_spec.rb +79 -0
  466. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +106 -0
  467. data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +1025 -0
  468. data/spec/mongoid/association/embedded/embeds_one_dnl_models.rb +8 -0
  469. data/spec/mongoid/association/embedded/embeds_one_models.rb +73 -0
  470. data/spec/mongoid/association/embedded/embeds_one_query_spec.rb +28 -0
  471. data/spec/mongoid/association/embedded/embeds_one_spec.rb +984 -0
  472. data/spec/mongoid/association/macros_spec.rb +1116 -0
  473. data/spec/mongoid/association/nested/many_spec.rb +232 -0
  474. data/spec/mongoid/association/nested/one_spec.rb +253 -0
  475. data/spec/mongoid/association/options_spec.rb +1323 -0
  476. data/spec/mongoid/association/polymorphic_spec.rb +162 -0
  477. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +244 -0
  478. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +292 -0
  479. data/spec/mongoid/association/referenced/belongs_to/eager_spec.rb +412 -0
  480. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +1388 -0
  481. data/spec/mongoid/association/referenced/belongs_to_models.rb +11 -0
  482. data/spec/mongoid/association/referenced/belongs_to_query_spec.rb +57 -0
  483. data/spec/mongoid/association/referenced/belongs_to_spec.rb +2046 -0
  484. data/spec/mongoid/association/referenced/has_and_belongs_to_many/binding_spec.rb +180 -0
  485. data/spec/mongoid/association/referenced/has_and_belongs_to_many/buildable_spec.rb +148 -0
  486. data/spec/mongoid/association/referenced/has_and_belongs_to_many/eager_spec.rb +196 -0
  487. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_persistence_spec.rb +76 -0
  488. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +3836 -0
  489. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +92 -0
  490. data/spec/mongoid/association/referenced/has_and_belongs_to_many_query_spec.rb +39 -0
  491. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +1104 -0
  492. data/spec/mongoid/association/referenced/has_many/binding_spec.rb +155 -0
  493. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +251 -0
  494. data/spec/mongoid/association/referenced/has_many/eager_spec.rb +290 -0
  495. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +2232 -0
  496. data/spec/mongoid/association/referenced/has_many/proxy_query_spec.rb +23 -0
  497. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +4161 -0
  498. data/spec/mongoid/association/referenced/has_many_models.rb +97 -0
  499. data/spec/mongoid/association/referenced/has_many_query_spec.rb +37 -0
  500. data/spec/mongoid/association/referenced/has_many_spec.rb +1273 -0
  501. data/spec/mongoid/association/referenced/has_one/binding_spec.rb +133 -0
  502. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +159 -0
  503. data/spec/mongoid/association/referenced/has_one/eager_spec.rb +193 -0
  504. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +1248 -0
  505. data/spec/mongoid/association/referenced/has_one_models.rb +113 -0
  506. data/spec/mongoid/association/referenced/has_one_query_spec.rb +37 -0
  507. data/spec/mongoid/association/referenced/has_one_spec.rb +1383 -0
  508. data/spec/mongoid/association/reflections_spec.rb +92 -0
  509. data/spec/mongoid/association/syncable_spec.rb +513 -0
  510. data/spec/mongoid/association_spec.rb +191 -0
  511. data/spec/mongoid/atomic/modifiers_spec.rb +88 -39
  512. data/spec/mongoid/atomic/paths/embedded/many_spec.rb +10 -49
  513. data/spec/mongoid/atomic/paths/embedded/one_spec.rb +9 -49
  514. data/spec/mongoid/atomic/paths/root_spec.rb +5 -61
  515. data/spec/mongoid/atomic/paths_spec.rb +115 -35
  516. data/spec/mongoid/atomic_spec.rb +89 -42
  517. data/spec/mongoid/attributes/dynamic_spec.rb +152 -0
  518. data/spec/mongoid/attributes/nested_spec.rb +5000 -0
  519. data/spec/mongoid/attributes/nested_spec_models.rb +48 -0
  520. data/spec/mongoid/attributes/projector_data/embedded.yml +105 -0
  521. data/spec/mongoid/attributes/projector_data/fields.yml +93 -0
  522. data/spec/mongoid/attributes/projector_spec.rb +40 -0
  523. data/spec/mongoid/attributes/readonly_spec.rb +166 -64
  524. data/spec/mongoid/attributes_spec.rb +1418 -409
  525. data/spec/mongoid/cacheable_spec.rb +114 -0
  526. data/spec/mongoid/changeable_spec.rb +1914 -0
  527. data/spec/mongoid/clients/factory_spec.rb +426 -0
  528. data/spec/mongoid/clients/options_spec.rb +521 -0
  529. data/spec/mongoid/clients/sessions_spec.rb +297 -0
  530. data/spec/mongoid/clients/transactions_spec.rb +415 -0
  531. data/spec/mongoid/clients_spec.rb +1084 -0
  532. data/spec/mongoid/composable_spec.rb +33 -0
  533. data/spec/mongoid/config/environment_spec.rb +138 -17
  534. data/spec/mongoid/config/options_spec.rb +26 -7
  535. data/spec/mongoid/config_spec.rb +607 -93
  536. data/spec/mongoid/contextual/aggregable/memory_spec.rb +433 -153
  537. data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
  538. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
  539. data/spec/mongoid/contextual/aggregable/mongo_spec.rb +221 -56
  540. data/spec/mongoid/contextual/aggregable/none_spec.rb +60 -0
  541. data/spec/mongoid/contextual/atomic_spec.rb +577 -162
  542. data/spec/mongoid/contextual/geo_near_spec.rb +104 -38
  543. data/spec/mongoid/contextual/map_reduce_spec.rb +137 -142
  544. data/spec/mongoid/contextual/memory_spec.rb +1880 -269
  545. data/spec/mongoid/contextual/mongo_spec.rb +2523 -601
  546. data/spec/mongoid/contextual/none_spec.rb +123 -0
  547. data/spec/mongoid/copyable_spec.rb +833 -76
  548. data/spec/mongoid/copyable_spec_models.rb +47 -0
  549. data/spec/mongoid/criteria/findable_spec.rb +1132 -0
  550. data/spec/mongoid/criteria/includable_spec.rb +1492 -0
  551. data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
  552. data/spec/mongoid/criteria/inspectable_spec.rb +29 -0
  553. data/spec/mongoid/criteria/marshalable_spec.rb +47 -0
  554. data/spec/mongoid/criteria/modifiable_spec.rb +1812 -0
  555. data/spec/mongoid/criteria/options_spec.rb +31 -0
  556. data/spec/mongoid/criteria/queryable/aggregable_spec.rb +372 -0
  557. data/spec/mongoid/criteria/queryable/expandable_spec.rb +61 -0
  558. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +513 -0
  559. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +169 -0
  560. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +60 -0
  561. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +215 -0
  562. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +343 -0
  563. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +434 -0
  564. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +60 -0
  565. data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +67 -0
  566. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +314 -0
  567. data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +67 -0
  568. data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +79 -0
  569. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +119 -0
  570. data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +110 -0
  571. data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +370 -0
  572. data/spec/mongoid/criteria/queryable/extensions/regexp_raw_spec.rb +91 -0
  573. data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +92 -0
  574. data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +41 -0
  575. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +347 -0
  576. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +169 -0
  577. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +406 -0
  578. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +387 -0
  579. data/spec/mongoid/criteria/queryable/key_spec.rb +96 -0
  580. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +182 -0
  581. data/spec/mongoid/criteria/queryable/optional_spec.rb +1317 -0
  582. data/spec/mongoid/criteria/queryable/options_spec.rb +362 -0
  583. data/spec/mongoid/criteria/queryable/pipeline_spec.rb +214 -0
  584. data/spec/mongoid/criteria/queryable/queryable_spec.rb +139 -0
  585. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +2119 -0
  586. data/spec/mongoid/criteria/queryable/selectable_shared_examples.rb +38 -0
  587. data/spec/mongoid/criteria/queryable/selectable_spec.rb +2462 -0
  588. data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +589 -0
  589. data/spec/mongoid/criteria/queryable/selector_spec.rb +895 -0
  590. data/spec/mongoid/criteria/queryable/smash_spec.rb +32 -0
  591. data/spec/mongoid/criteria/queryable/storable_spec.rb +226 -0
  592. data/spec/mongoid/criteria/scopable_spec.rb +601 -0
  593. data/spec/mongoid/criteria_projection_spec.rb +410 -0
  594. data/spec/mongoid/criteria_spec.rb +1828 -3572
  595. data/spec/mongoid/document_fields_spec.rb +262 -0
  596. data/spec/mongoid/document_persistence_context_spec.rb +32 -0
  597. data/spec/mongoid/document_query_spec.rb +89 -0
  598. data/spec/mongoid/document_spec.rb +452 -221
  599. data/spec/mongoid/equality_spec.rb +155 -52
  600. data/spec/mongoid/errors/ambiguous_relationship_spec.rb +8 -6
  601. data/spec/mongoid/errors/callback_spec.rb +5 -3
  602. data/spec/mongoid/errors/delete_restriction_spec.rb +7 -5
  603. data/spec/mongoid/errors/document_not_destroyed_spec.rb +35 -0
  604. data/spec/mongoid/errors/document_not_found_spec.rb +89 -11
  605. data/spec/mongoid/errors/invalid_collection_spec.rb +5 -3
  606. data/spec/mongoid/errors/invalid_config_file_spec.rb +31 -0
  607. data/spec/mongoid/errors/invalid_config_option_spec.rb +5 -3
  608. data/spec/mongoid/errors/invalid_field_option_spec.rb +5 -3
  609. data/spec/mongoid/errors/invalid_field_spec.rb +6 -4
  610. data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
  611. data/spec/mongoid/errors/invalid_find_spec.rb +5 -3
  612. data/spec/mongoid/errors/invalid_includes_spec.rb +5 -3
  613. data/spec/mongoid/errors/invalid_index_spec.rb +5 -3
  614. data/spec/mongoid/errors/invalid_options_spec.rb +7 -5
  615. data/spec/mongoid/errors/invalid_path_spec.rb +5 -3
  616. data/spec/mongoid/errors/invalid_relation_spec.rb +39 -0
  617. data/spec/mongoid/errors/invalid_scope_spec.rb +7 -5
  618. data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +5 -3
  619. data/spec/mongoid/errors/invalid_storage_options_spec.rb +5 -3
  620. data/spec/mongoid/errors/invalid_time_spec.rb +5 -3
  621. data/spec/mongoid/errors/inverse_not_found_spec.rb +6 -4
  622. data/spec/mongoid/errors/mixed_client_configuration_spec.rb +31 -0
  623. data/spec/mongoid/errors/mixed_relations_spec.rb +5 -3
  624. data/spec/mongoid/errors/mongoid_error_spec.rb +45 -10
  625. data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +8 -6
  626. data/spec/mongoid/errors/no_client_config_spec.rb +31 -0
  627. data/spec/mongoid/errors/no_client_database_spec.rb +31 -0
  628. data/spec/mongoid/errors/no_client_hosts_spec.rb +31 -0
  629. data/spec/mongoid/errors/no_clients_config_spec.rb +31 -0
  630. data/spec/mongoid/errors/no_environment_spec.rb +8 -6
  631. data/spec/mongoid/errors/no_map_reduce_output_spec.rb +5 -3
  632. data/spec/mongoid/errors/no_metadata_spec.rb +5 -3
  633. data/spec/mongoid/errors/no_parent_spec.rb +6 -4
  634. data/spec/mongoid/errors/readonly_attribute_spec.rb +5 -3
  635. data/spec/mongoid/errors/readonly_document_spec.rb +31 -0
  636. data/spec/mongoid/errors/scope_overwrite_spec.rb +5 -3
  637. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +6 -4
  638. data/spec/mongoid/errors/unknown_attribute_spec.rb +7 -5
  639. data/spec/mongoid/errors/unsaved_document_spec.rb +6 -4
  640. data/spec/mongoid/errors/unsupported_javascript_spec.rb +5 -3
  641. data/spec/mongoid/errors/validations_spec.rb +9 -7
  642. data/spec/mongoid/extensions/array_spec.rb +108 -116
  643. data/spec/mongoid/extensions/big_decimal_spec.rb +838 -49
  644. data/spec/mongoid/extensions/binary_spec.rb +55 -18
  645. data/spec/mongoid/extensions/boolean_spec.rb +76 -74
  646. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +339 -0
  647. data/spec/mongoid/extensions/date_spec.rb +59 -145
  648. data/spec/mongoid/extensions/date_time_spec.rb +35 -76
  649. data/spec/mongoid/extensions/decimal128_spec.rb +46 -0
  650. data/spec/mongoid/extensions/false_class_spec.rb +7 -5
  651. data/spec/mongoid/extensions/float_spec.rb +69 -62
  652. data/spec/mongoid/extensions/hash_spec.rb +197 -30
  653. data/spec/mongoid/extensions/integer_spec.rb +63 -65
  654. data/spec/mongoid/extensions/module_spec.rb +4 -2
  655. data/spec/mongoid/extensions/nil_class_spec.rb +3 -1
  656. data/spec/mongoid/extensions/object_id_spec.rb +136 -134
  657. data/spec/mongoid/extensions/object_spec.rb +53 -57
  658. data/spec/mongoid/extensions/range_spec.rb +287 -28
  659. data/spec/mongoid/extensions/regexp_spec.rb +71 -21
  660. data/spec/mongoid/extensions/set_spec.rb +112 -4
  661. data/spec/mongoid/extensions/string_spec.rb +188 -89
  662. data/spec/mongoid/extensions/stringified_symbol_spec.rb +84 -0
  663. data/spec/mongoid/extensions/symbol_spec.rb +25 -30
  664. data/spec/mongoid/extensions/time_spec.rb +703 -110
  665. data/spec/mongoid/extensions/time_with_zone_spec.rb +82 -67
  666. data/spec/mongoid/extensions/true_class_spec.rb +7 -5
  667. data/spec/mongoid/extensions_spec.rb +43 -0
  668. data/spec/mongoid/factory_spec.rb +374 -25
  669. data/spec/mongoid/fields/foreign_key_spec.rb +116 -92
  670. data/spec/mongoid/fields/localized_spec.rb +177 -35
  671. data/spec/mongoid/fields/standard_spec.rb +15 -13
  672. data/spec/mongoid/fields_spec.rb +952 -238
  673. data/spec/mongoid/findable_spec.rb +632 -0
  674. data/spec/mongoid/indexable/specification_spec.rb +129 -0
  675. data/spec/mongoid/indexable_spec.rb +643 -0
  676. data/spec/mongoid/inspectable_spec.rb +86 -0
  677. data/spec/mongoid/interceptable_spec.rb +2373 -0
  678. data/spec/mongoid/interceptable_spec_models.rb +307 -0
  679. data/spec/mongoid/loggable_spec.rb +3 -1
  680. data/spec/mongoid/matcher/extract_attribute_data/numeric_keys.yml +104 -0
  681. data/spec/mongoid/matcher/extract_attribute_data/traversal.yml +239 -0
  682. data/spec/mongoid/matcher/extract_attribute_spec.rb +36 -0
  683. data/spec/mongoid/mongoizable_spec.rb +285 -0
  684. data/spec/mongoid/persistable/creatable_spec.rb +662 -0
  685. data/spec/mongoid/persistable/deletable_spec.rb +514 -0
  686. data/spec/mongoid/persistable/destroyable_spec.rb +455 -0
  687. data/spec/mongoid/persistable/incrementable_spec.rb +241 -0
  688. data/spec/mongoid/persistable/logical_spec.rb +159 -0
  689. data/spec/mongoid/persistable/poppable_spec.rb +131 -0
  690. data/spec/mongoid/persistable/pullable_spec.rb +258 -0
  691. data/spec/mongoid/persistable/pushable_spec.rb +353 -0
  692. data/spec/mongoid/persistable/renamable_spec.rb +151 -0
  693. data/spec/mongoid/persistable/savable_spec.rb +684 -0
  694. data/spec/mongoid/persistable/settable_spec.rb +544 -0
  695. data/spec/mongoid/persistable/unsettable_spec.rb +171 -0
  696. data/spec/mongoid/persistable/updatable_spec.rb +760 -0
  697. data/spec/mongoid/persistable/upsertable_spec.rb +122 -0
  698. data/spec/mongoid/persistable_spec.rb +321 -0
  699. data/spec/mongoid/persistence_context_spec.rb +745 -0
  700. data/spec/mongoid/positional_spec.rb +223 -0
  701. data/spec/mongoid/query_cache_middleware_spec.rb +50 -0
  702. data/spec/mongoid/query_cache_spec.rb +870 -0
  703. data/spec/mongoid/relations/proxy_spec.rb +125 -47
  704. data/spec/mongoid/reloadable_spec.rb +665 -0
  705. data/spec/mongoid/scopable_spec.rb +1234 -0
  706. data/spec/mongoid/selectable_spec.rb +136 -0
  707. data/spec/mongoid/serializable_spec.rb +963 -0
  708. data/spec/mongoid/shardable_models.rb +61 -0
  709. data/spec/mongoid/shardable_spec.rb +204 -0
  710. data/spec/mongoid/stateful_spec.rb +157 -0
  711. data/spec/mongoid/tasks/database_rake_spec.rb +287 -0
  712. data/spec/mongoid/tasks/database_spec.rb +181 -0
  713. data/spec/mongoid/threaded_spec.rb +88 -78
  714. data/spec/mongoid/timestamps/created/short_spec.rb +9 -7
  715. data/spec/mongoid/timestamps/created_spec.rb +8 -6
  716. data/spec/mongoid/timestamps/timeless_spec.rb +29 -10
  717. data/spec/mongoid/timestamps/updated/short_spec.rb +16 -14
  718. data/spec/mongoid/timestamps/updated_spec.rb +14 -16
  719. data/spec/mongoid/timestamps_spec.rb +406 -18
  720. data/spec/mongoid/timestamps_spec_models.rb +67 -0
  721. data/spec/mongoid/touchable_spec.rb +704 -0
  722. data/spec/mongoid/touchable_spec_models.rb +57 -0
  723. data/spec/mongoid/traversable_spec.rb +1410 -0
  724. data/spec/mongoid/validatable/associated_spec.rb +208 -0
  725. data/spec/mongoid/validatable/format_spec.rb +85 -0
  726. data/spec/mongoid/validatable/length_spec.rb +225 -0
  727. data/spec/mongoid/validatable/numericality_spec.rb +32 -0
  728. data/spec/mongoid/validatable/presence_spec.rb +592 -0
  729. data/spec/mongoid/validatable/uniqueness_spec.rb +2504 -0
  730. data/spec/mongoid/validatable_spec.rb +327 -0
  731. data/spec/mongoid/warnings_spec.rb +35 -0
  732. data/spec/mongoid_spec.rb +20 -20
  733. data/spec/rails/controller_extension/controller_runtime_spec.rb +112 -0
  734. data/spec/rails/mongoid_spec.rb +37 -354
  735. data/spec/shared/LICENSE +20 -0
  736. data/spec/shared/bin/get-mongodb-download-url +17 -0
  737. data/spec/shared/bin/s3-copy +45 -0
  738. data/spec/shared/bin/s3-upload +69 -0
  739. data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
  740. data/spec/shared/lib/mrss/cluster_config.rb +231 -0
  741. data/spec/shared/lib/mrss/constraints.rb +378 -0
  742. data/spec/shared/lib/mrss/docker_runner.rb +291 -0
  743. data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
  744. data/spec/shared/lib/mrss/event_subscriber.rb +200 -0
  745. data/spec/shared/lib/mrss/lite_constraints.rb +230 -0
  746. data/spec/shared/lib/mrss/server_version_registry.rb +120 -0
  747. data/spec/shared/lib/mrss/session_registry.rb +69 -0
  748. data/spec/shared/lib/mrss/session_registry_legacy.rb +60 -0
  749. data/spec/shared/lib/mrss/spec_organizer.rb +179 -0
  750. data/spec/shared/lib/mrss/utils.rb +15 -0
  751. data/spec/shared/share/Dockerfile.erb +325 -0
  752. data/spec/shared/share/haproxy-1.conf +16 -0
  753. data/spec/shared/share/haproxy-2.conf +17 -0
  754. data/spec/shared/shlib/config.sh +27 -0
  755. data/spec/shared/shlib/distro.sh +74 -0
  756. data/spec/shared/shlib/server.sh +392 -0
  757. data/spec/shared/shlib/set_env.sh +169 -0
  758. data/spec/spec_helper.rb +163 -42
  759. data/spec/support/authorization.rb +15 -0
  760. data/spec/support/client_registry.rb +9 -0
  761. data/spec/support/constraints.rb +77 -0
  762. data/spec/support/expectations.rb +32 -0
  763. data/spec/support/helpers.rb +11 -0
  764. data/spec/support/macros.rb +81 -0
  765. data/spec/support/models/account.rb +38 -0
  766. data/spec/support/models/acolyte.rb +19 -0
  767. data/spec/support/models/actor.rb +20 -0
  768. data/spec/support/models/actress.rb +4 -0
  769. data/spec/support/models/address.rb +85 -0
  770. data/spec/support/models/address_component.rb +7 -0
  771. data/spec/support/models/address_number.rb +8 -0
  772. data/spec/support/models/agency.rb +7 -0
  773. data/spec/support/models/agent.rb +18 -0
  774. data/spec/support/models/album.rb +20 -0
  775. data/spec/support/models/alert.rb +9 -0
  776. data/spec/support/models/animal.rb +28 -0
  777. data/spec/support/models/answer.rb +8 -0
  778. data/spec/support/models/appointment.rb +9 -0
  779. data/spec/support/models/armrest.rb +9 -0
  780. data/spec/support/models/array_field.rb +7 -0
  781. data/spec/support/models/article.rb +14 -0
  782. data/spec/support/models/artist.rb +91 -0
  783. data/spec/support/models/artwork.rb +6 -0
  784. data/spec/support/models/audible_sound.rb +3 -0
  785. data/spec/support/models/audio.rb +7 -0
  786. data/spec/support/models/augmentation.rb +25 -0
  787. data/spec/support/models/author.rb +8 -0
  788. data/spec/support/models/baby.rb +6 -0
  789. data/spec/support/models/band.rb +40 -0
  790. data/spec/support/models/bar.rb +12 -0
  791. data/spec/support/models/basic.rb +8 -0
  792. data/spec/support/models/bed.rb +3 -0
  793. data/spec/support/models/big_palette.rb +4 -0
  794. data/spec/support/models/birthday.rb +15 -0
  795. data/spec/support/models/bolt.rb +7 -0
  796. data/spec/support/models/bomb.rb +6 -0
  797. data/spec/support/models/book.rb +18 -0
  798. data/spec/support/models/breed.rb +6 -0
  799. data/spec/support/models/browser.rb +8 -0
  800. data/spec/support/models/building.rb +8 -0
  801. data/spec/support/models/building_address.rb +9 -0
  802. data/spec/support/models/bus.rb +9 -0
  803. data/spec/support/models/business.rb +7 -0
  804. data/spec/support/models/callback_test.rb +11 -0
  805. data/spec/support/models/canvas.rb +27 -0
  806. data/spec/support/models/car.rb +3 -0
  807. data/spec/support/models/cat.rb +10 -0
  808. data/spec/support/models/catalog.rb +24 -0
  809. data/spec/support/models/category.rb +10 -0
  810. data/spec/support/models/child.rb +6 -0
  811. data/spec/support/models/child_doc.rb +24 -0
  812. data/spec/support/models/church.rb +8 -0
  813. data/spec/support/models/circle.rb +5 -0
  814. data/spec/support/models/circuit.rb +6 -0
  815. data/spec/support/models/circus.rb +12 -0
  816. data/spec/support/models/code.rb +15 -0
  817. data/spec/support/models/coding/pull_request.rb +11 -0
  818. data/spec/support/models/coding.rb +3 -0
  819. data/spec/support/models/comment.rb +18 -0
  820. data/spec/support/models/company.rb +7 -0
  821. data/spec/support/models/consumption_period.rb +9 -0
  822. data/spec/support/models/contextable_item.rb +7 -0
  823. data/spec/support/models/contractor.rb +7 -0
  824. data/spec/support/models/cookie.rb +8 -0
  825. data/spec/support/models/country_code.rb +12 -0
  826. data/spec/support/models/courier_job.rb +6 -0
  827. data/spec/support/models/crate.rb +12 -0
  828. data/spec/support/models/customer.rb +10 -0
  829. data/spec/support/models/customer_address.rb +11 -0
  830. data/spec/support/models/deed.rb +7 -0
  831. data/spec/support/models/definition.rb +11 -0
  832. data/spec/support/models/delegating_patient.rb +15 -0
  833. data/spec/support/models/description.rb +13 -0
  834. data/spec/support/models/dictionary.rb +18 -0
  835. data/spec/support/models/division.rb +12 -0
  836. data/spec/support/models/doctor.rb +14 -0
  837. data/spec/support/models/dog.rb +9 -0
  838. data/spec/support/models/dokument.rb +8 -0
  839. data/spec/support/models/draft.rb +11 -0
  840. data/spec/support/models/dragon.rb +6 -0
  841. data/spec/support/models/driver.rb +9 -0
  842. data/spec/support/models/drug.rb +8 -0
  843. data/spec/support/models/dungeon.rb +6 -0
  844. data/spec/support/models/edit.rb +7 -0
  845. data/spec/support/models/email.rb +8 -0
  846. data/spec/support/models/employer.rb +7 -0
  847. data/spec/support/models/entry.rb +8 -0
  848. data/spec/support/models/eraser.rb +3 -0
  849. data/spec/support/models/even.rb +9 -0
  850. data/spec/support/models/event.rb +24 -0
  851. data/spec/support/models/exhibition.rb +6 -0
  852. data/spec/support/models/exhibitor.rb +8 -0
  853. data/spec/support/models/explosion.rb +6 -0
  854. data/spec/support/models/eye.rb +11 -0
  855. data/spec/support/models/eye_bowl.rb +11 -0
  856. data/spec/support/models/face.rb +10 -0
  857. data/spec/support/models/fanatic.rb +8 -0
  858. data/spec/support/models/favorite.rb +8 -0
  859. data/spec/support/models/filesystem.rb +7 -0
  860. data/spec/support/models/fire_hydrant.rb +8 -0
  861. data/spec/support/models/firefox.rb +6 -0
  862. data/spec/support/models/fish.rb +9 -0
  863. data/spec/support/models/folder.rb +9 -0
  864. data/spec/support/models/folder_item.rb +11 -0
  865. data/spec/support/models/fruits.rb +36 -0
  866. data/spec/support/models/game.rb +21 -0
  867. data/spec/support/models/ghost.rb +9 -0
  868. data/spec/support/models/guitar.rb +4 -0
  869. data/spec/support/models/hole.rb +12 -0
  870. data/spec/support/models/home.rb +6 -0
  871. data/spec/support/models/house.rb +8 -0
  872. data/spec/support/models/html_writer.rb +5 -0
  873. data/spec/support/models/id_key.rb +8 -0
  874. data/spec/support/models/idnodef.rb +7 -0
  875. data/spec/support/models/image.rb +24 -0
  876. data/spec/support/models/implant.rb +27 -0
  877. data/spec/support/models/instrument.rb +8 -0
  878. data/spec/support/models/item.rb +10 -0
  879. data/spec/support/models/jar.rb +9 -0
  880. data/spec/support/models/kaleidoscope.rb +8 -0
  881. data/spec/support/models/kangaroo.rb +6 -0
  882. data/spec/support/models/label.rb +52 -0
  883. data/spec/support/models/language.rb +7 -0
  884. data/spec/support/models/lat_lng.rb +17 -0
  885. data/spec/support/models/league.rb +13 -0
  886. data/spec/support/models/learner.rb +4 -0
  887. data/spec/support/models/line_item.rb +8 -0
  888. data/spec/support/models/location.rb +10 -0
  889. data/spec/support/models/login.rb +10 -0
  890. data/spec/support/models/manufacturer.rb +9 -0
  891. data/spec/support/models/meat.rb +6 -0
  892. data/spec/support/models/membership.rb +7 -0
  893. data/spec/support/models/message.rb +13 -0
  894. data/spec/support/models/minim.rb +6 -0
  895. data/spec/support/models/mixed_drink.rb +6 -0
  896. data/spec/support/models/mop.rb +24 -0
  897. data/spec/support/models/movie.rb +15 -0
  898. data/spec/support/models/my_hash.rb +4 -0
  899. data/spec/support/models/name.rb +26 -0
  900. data/spec/support/models/name_only.rb +8 -0
  901. data/spec/support/models/node.rb +7 -0
  902. data/spec/support/models/note.rb +19 -0
  903. data/spec/support/models/nut.rb +7 -0
  904. data/spec/support/models/odd.rb +9 -0
  905. data/spec/support/models/order.rb +12 -0
  906. data/spec/support/models/ordered_post.rb +13 -0
  907. data/spec/support/models/ordered_preference.rb +8 -0
  908. data/spec/support/models/oscar.rb +16 -0
  909. data/spec/support/models/other_owner_object.rb +4 -0
  910. data/spec/support/models/override.rb +18 -0
  911. data/spec/support/models/ownable.rb +8 -0
  912. data/spec/support/models/owner.rb +10 -0
  913. data/spec/support/models/pack.rb +5 -0
  914. data/spec/support/models/page.rb +18 -0
  915. data/spec/support/models/page_question.rb +6 -0
  916. data/spec/support/models/palette.rb +9 -0
  917. data/spec/support/models/parent.rb +7 -0
  918. data/spec/support/models/parent_doc.rb +8 -0
  919. data/spec/support/models/passport.rb +22 -0
  920. data/spec/support/models/patient.rb +11 -0
  921. data/spec/support/models/pdf_writer.rb +5 -0
  922. data/spec/support/models/pencil.rb +3 -0
  923. data/spec/support/models/person.rb +231 -0
  924. data/spec/support/models/pet.rb +25 -0
  925. data/spec/support/models/pet_owner.rb +8 -0
  926. data/spec/support/models/phone.rb +13 -0
  927. data/spec/support/models/piano.rb +4 -0
  928. data/spec/support/models/pizza.rb +9 -0
  929. data/spec/support/models/player.rb +39 -0
  930. data/spec/support/models/post.rb +52 -0
  931. data/spec/support/models/post_genre.rb +8 -0
  932. data/spec/support/models/powerup.rb +25 -0
  933. data/spec/support/models/preference.rb +11 -0
  934. data/spec/support/models/princess.rb +12 -0
  935. data/spec/support/models/product.rb +19 -0
  936. data/spec/support/models/profile.rb +17 -0
  937. data/spec/support/models/pronunciation.rb +7 -0
  938. data/spec/support/models/pub.rb +8 -0
  939. data/spec/support/models/publication/encyclopedia.rb +11 -0
  940. data/spec/support/models/publication/review.rb +13 -0
  941. data/spec/support/models/publication.rb +4 -0
  942. data/spec/support/models/purchase.rb +6 -0
  943. data/spec/support/models/purchased_item.rb +10 -0
  944. data/spec/support/models/question.rb +10 -0
  945. data/spec/support/models/quiz.rb +9 -0
  946. data/spec/support/models/rating.rb +10 -0
  947. data/spec/support/models/record.rb +54 -0
  948. data/spec/support/models/registry.rb +7 -0
  949. data/spec/support/models/role.rb +9 -0
  950. data/spec/support/models/root_category.rb +6 -0
  951. data/spec/support/models/sandwich.rb +11 -0
  952. data/spec/support/models/scheduler.rb +9 -0
  953. data/spec/support/models/school.rb +14 -0
  954. data/spec/support/models/scribe.rb +7 -0
  955. data/spec/support/models/sealer.rb +7 -0
  956. data/spec/support/models/seat.rb +24 -0
  957. data/spec/support/models/seo.rb +9 -0
  958. data/spec/support/models/series.rb +7 -0
  959. data/spec/support/models/server.rb +15 -0
  960. data/spec/support/models/service.rb +24 -0
  961. data/spec/support/models/shape.rb +14 -0
  962. data/spec/support/models/shelf.rb +7 -0
  963. data/spec/support/models/shield.rb +18 -0
  964. data/spec/support/models/shipment_address.rb +5 -0
  965. data/spec/support/models/shipping_container.rb +7 -0
  966. data/spec/support/models/shipping_pack.rb +5 -0
  967. data/spec/support/models/shirt.rb +11 -0
  968. data/spec/support/models/shop.rb +8 -0
  969. data/spec/support/models/short_agent.rb +6 -0
  970. data/spec/support/models/short_quiz.rb +7 -0
  971. data/spec/support/models/simple.rb +7 -0
  972. data/spec/support/models/slave.rb +8 -0
  973. data/spec/support/models/song.rb +10 -0
  974. data/spec/support/models/sound.rb +7 -0
  975. data/spec/support/models/spacer.rb +7 -0
  976. data/spec/support/models/square.rb +6 -0
  977. data/spec/support/models/staff.rb +9 -0
  978. data/spec/support/models/store_as_dup_test1.rb +7 -0
  979. data/spec/support/models/store_as_dup_test2.rb +7 -0
  980. data/spec/support/models/store_as_dup_test3.rb +7 -0
  981. data/spec/support/models/store_as_dup_test4.rb +7 -0
  982. data/spec/support/models/strategy.rb +5 -0
  983. data/spec/support/models/student.rb +14 -0
  984. data/spec/support/models/sub_item.rb +5 -0
  985. data/spec/support/models/subscription.rb +7 -0
  986. data/spec/support/models/survey.rb +7 -0
  987. data/spec/support/models/symptom.rb +8 -0
  988. data/spec/support/models/system_role.rb +7 -0
  989. data/spec/support/models/tag.rb +10 -0
  990. data/spec/support/models/target.rb +7 -0
  991. data/spec/support/models/template.rb +7 -0
  992. data/spec/support/models/thing.rb +11 -0
  993. data/spec/support/models/threadlocker.rb +7 -0
  994. data/spec/support/models/title.rb +5 -0
  995. data/spec/support/models/tool.rb +10 -0
  996. data/spec/support/models/topping.rb +7 -0
  997. data/spec/support/models/toy.rb +9 -0
  998. data/spec/support/models/track.rb +40 -0
  999. data/spec/support/models/translation.rb +7 -0
  1000. data/spec/support/models/tree.rb +11 -0
  1001. data/spec/support/models/truck.rb +7 -0
  1002. data/spec/support/models/updatable.rb +7 -0
  1003. data/spec/support/models/user.rb +23 -0
  1004. data/spec/support/models/user_account.rb +12 -0
  1005. data/spec/support/models/validation_callback.rb +12 -0
  1006. data/spec/support/models/vehicle.rb +18 -0
  1007. data/spec/support/models/version.rb +7 -0
  1008. data/spec/support/models/vertex.rb +8 -0
  1009. data/spec/support/models/vet_visit.rb +7 -0
  1010. data/spec/support/models/video.rb +15 -0
  1011. data/spec/support/models/video_game.rb +3 -0
  1012. data/spec/support/models/washer.rb +7 -0
  1013. data/spec/support/models/weapon.rb +25 -0
  1014. data/spec/support/models/wiki_page.rb +17 -0
  1015. data/spec/support/models/word.rb +17 -0
  1016. data/spec/support/models/word_origin.rb +13 -0
  1017. data/spec/support/models/writer.rb +13 -0
  1018. data/spec/support/schema_maps/schema_map_aws.json +17 -0
  1019. data/spec/support/schema_maps/schema_map_aws_key_alt_names.json +12 -0
  1020. data/spec/support/schema_maps/schema_map_azure.json +17 -0
  1021. data/spec/support/schema_maps/schema_map_azure_key_alt_names.json +12 -0
  1022. data/spec/support/schema_maps/schema_map_gcp.json +17 -0
  1023. data/spec/support/schema_maps/schema_map_gcp_key_alt_names.json +12 -0
  1024. data/spec/support/schema_maps/schema_map_kmip.json +17 -0
  1025. data/spec/support/schema_maps/schema_map_kmip_key_alt_names.json +12 -0
  1026. data/spec/support/schema_maps/schema_map_local.json +18 -0
  1027. data/spec/support/schema_maps/schema_map_local_key_alt_names.json +12 -0
  1028. data/spec/support/shared/time.rb +53 -0
  1029. data/spec/support/spec_config.rb +64 -0
  1030. data.tar.gz.sig +0 -0
  1031. metadata +1582 -912
  1032. metadata.gz.sig +0 -0
  1033. data/lib/mongoid/atomic/positionable.rb +0 -73
  1034. data/lib/mongoid/callbacks.rb +0 -314
  1035. data/lib/mongoid/components.rb +0 -93
  1036. data/lib/mongoid/config/inflections.rb +0 -6
  1037. data/lib/mongoid/config/validators/session.rb +0 -140
  1038. data/lib/mongoid/contextual/eager.rb +0 -158
  1039. data/lib/mongoid/contextual/find_and_modify.rb +0 -69
  1040. data/lib/mongoid/criterion/findable.rb +0 -179
  1041. data/lib/mongoid/criterion/inspection.rb +0 -25
  1042. data/lib/mongoid/criterion/marshalable.rb +0 -48
  1043. data/lib/mongoid/criterion/modifiable.rb +0 -189
  1044. data/lib/mongoid/criterion/scoping.rb +0 -158
  1045. data/lib/mongoid/dirty.rb +0 -376
  1046. data/lib/mongoid/errors/eager_load.rb +0 -22
  1047. data/lib/mongoid/errors/mixed_session_configuration.rb +0 -28
  1048. data/lib/mongoid/errors/no_default_session.rb +0 -23
  1049. data/lib/mongoid/errors/no_session_config.rb +0 -22
  1050. data/lib/mongoid/errors/no_session_database.rb +0 -27
  1051. data/lib/mongoid/errors/no_session_hosts.rb +0 -27
  1052. data/lib/mongoid/errors/no_sessions_config.rb +0 -20
  1053. data/lib/mongoid/errors/versioning_not_on_root.rb +0 -23
  1054. data/lib/mongoid/finders.rb +0 -130
  1055. data/lib/mongoid/hierarchy.rb +0 -188
  1056. data/lib/mongoid/identity_map.rb +0 -163
  1057. data/lib/mongoid/indexes/validators/options.rb +0 -102
  1058. data/lib/mongoid/indexes.rb +0 -154
  1059. data/lib/mongoid/inspection.rb +0 -55
  1060. data/lib/mongoid/json.rb +0 -16
  1061. data/lib/mongoid/matchers/all.rb +0 -27
  1062. data/lib/mongoid/matchers/and.rb +0 -30
  1063. data/lib/mongoid/matchers/default.rb +0 -72
  1064. data/lib/mongoid/matchers/exists.rb +0 -23
  1065. data/lib/mongoid/matchers/gt.rb +0 -21
  1066. data/lib/mongoid/matchers/gte.rb +0 -21
  1067. data/lib/mongoid/matchers/in.rb +0 -24
  1068. data/lib/mongoid/matchers/lt.rb +0 -21
  1069. data/lib/mongoid/matchers/lte.rb +0 -21
  1070. data/lib/mongoid/matchers/ne.rb +0 -21
  1071. data/lib/mongoid/matchers/nin.rb +0 -21
  1072. data/lib/mongoid/matchers/or.rb +0 -33
  1073. data/lib/mongoid/matchers/size.rb +0 -21
  1074. data/lib/mongoid/matchers/strategies.rb +0 -97
  1075. data/lib/mongoid/matchers.rb +0 -32
  1076. data/lib/mongoid/multi_parameter_attributes.rb +0 -105
  1077. data/lib/mongoid/nested_attributes.rb +0 -78
  1078. data/lib/mongoid/observer.rb +0 -192
  1079. data/lib/mongoid/paranoia.rb +0 -137
  1080. data/lib/mongoid/persistence/atomic/add_to_set.rb +0 -47
  1081. data/lib/mongoid/persistence/atomic/bit.rb +0 -35
  1082. data/lib/mongoid/persistence/atomic/inc.rb +0 -45
  1083. data/lib/mongoid/persistence/atomic/operation.rb +0 -154
  1084. data/lib/mongoid/persistence/atomic/pop.rb +0 -32
  1085. data/lib/mongoid/persistence/atomic/pull.rb +0 -32
  1086. data/lib/mongoid/persistence/atomic/pull_all.rb +0 -32
  1087. data/lib/mongoid/persistence/atomic/push.rb +0 -25
  1088. data/lib/mongoid/persistence/atomic/push_all.rb +0 -25
  1089. data/lib/mongoid/persistence/atomic/rename.rb +0 -30
  1090. data/lib/mongoid/persistence/atomic/sets.rb +0 -28
  1091. data/lib/mongoid/persistence/atomic/unset.rb +0 -27
  1092. data/lib/mongoid/persistence/atomic.rb +0 -231
  1093. data/lib/mongoid/persistence/deletion.rb +0 -32
  1094. data/lib/mongoid/persistence/insertion.rb +0 -38
  1095. data/lib/mongoid/persistence/modification.rb +0 -35
  1096. data/lib/mongoid/persistence/operations/embedded/insert.rb +0 -46
  1097. data/lib/mongoid/persistence/operations/embedded/remove.rb +0 -43
  1098. data/lib/mongoid/persistence/operations/insert.rb +0 -34
  1099. data/lib/mongoid/persistence/operations/remove.rb +0 -33
  1100. data/lib/mongoid/persistence/operations/update.rb +0 -59
  1101. data/lib/mongoid/persistence/operations/upsert.rb +0 -28
  1102. data/lib/mongoid/persistence/operations.rb +0 -214
  1103. data/lib/mongoid/persistence/upsertion.rb +0 -31
  1104. data/lib/mongoid/persistence.rb +0 -352
  1105. data/lib/mongoid/railties/document.rb +0 -12
  1106. data/lib/mongoid/relations/accessors.rb +0 -299
  1107. data/lib/mongoid/relations/auto_save.rb +0 -107
  1108. data/lib/mongoid/relations/binding.rb +0 -241
  1109. data/lib/mongoid/relations/bindings/embedded/in.rb +0 -63
  1110. data/lib/mongoid/relations/bindings/embedded/many.rb +0 -52
  1111. data/lib/mongoid/relations/bindings/embedded/one.rb +0 -55
  1112. data/lib/mongoid/relations/bindings/referenced/in.rb +0 -70
  1113. data/lib/mongoid/relations/bindings/referenced/many.rb +0 -42
  1114. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +0 -67
  1115. data/lib/mongoid/relations/bindings/referenced/one.rb +0 -44
  1116. data/lib/mongoid/relations/bindings.rb +0 -9
  1117. data/lib/mongoid/relations/builder.rb +0 -57
  1118. data/lib/mongoid/relations/builders/embedded/in.rb +0 -29
  1119. data/lib/mongoid/relations/builders/embedded/many.rb +0 -36
  1120. data/lib/mongoid/relations/builders/embedded/one.rb +0 -30
  1121. data/lib/mongoid/relations/builders/nested_attributes/many.rb +0 -177
  1122. data/lib/mongoid/relations/builders/nested_attributes/one.rb +0 -127
  1123. data/lib/mongoid/relations/builders/referenced/in.rb +0 -26
  1124. data/lib/mongoid/relations/builders/referenced/many.rb +0 -27
  1125. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +0 -40
  1126. data/lib/mongoid/relations/builders/referenced/one.rb +0 -26
  1127. data/lib/mongoid/relations/builders.rb +0 -104
  1128. data/lib/mongoid/relations/cascading/delete.rb +0 -44
  1129. data/lib/mongoid/relations/cascading/destroy.rb +0 -43
  1130. data/lib/mongoid/relations/cascading/nullify.rb +0 -35
  1131. data/lib/mongoid/relations/cascading/restrict.rb +0 -39
  1132. data/lib/mongoid/relations/cascading.rb +0 -58
  1133. data/lib/mongoid/relations/constraint.rb +0 -49
  1134. data/lib/mongoid/relations/conversions.rb +0 -34
  1135. data/lib/mongoid/relations/counter_cache.rb +0 -107
  1136. data/lib/mongoid/relations/cyclic.rb +0 -107
  1137. data/lib/mongoid/relations/embedded/batchable.rb +0 -356
  1138. data/lib/mongoid/relations/embedded/in.rb +0 -231
  1139. data/lib/mongoid/relations/embedded/many.rb +0 -659
  1140. data/lib/mongoid/relations/embedded/one.rb +0 -223
  1141. data/lib/mongoid/relations/macros.rb +0 -359
  1142. data/lib/mongoid/relations/many.rb +0 -217
  1143. data/lib/mongoid/relations/marshalable.rb +0 -32
  1144. data/lib/mongoid/relations/metadata.rb +0 -1227
  1145. data/lib/mongoid/relations/nested_builder.rb +0 -74
  1146. data/lib/mongoid/relations/one.rb +0 -60
  1147. data/lib/mongoid/relations/options.rb +0 -48
  1148. data/lib/mongoid/relations/polymorphic.rb +0 -40
  1149. data/lib/mongoid/relations/proxy.rb +0 -264
  1150. data/lib/mongoid/relations/referenced/in.rb +0 -314
  1151. data/lib/mongoid/relations/referenced/many.rb +0 -789
  1152. data/lib/mongoid/relations/referenced/many_to_many.rb +0 -495
  1153. data/lib/mongoid/relations/referenced/one.rb +0 -297
  1154. data/lib/mongoid/relations/reflections.rb +0 -62
  1155. data/lib/mongoid/relations/synchronization.rb +0 -169
  1156. data/lib/mongoid/relations/targets/enumerable.rb +0 -473
  1157. data/lib/mongoid/relations/targets.rb +0 -2
  1158. data/lib/mongoid/relations/touchable.rb +0 -61
  1159. data/lib/mongoid/relations.rb +0 -162
  1160. data/lib/mongoid/reloading.rb +0 -92
  1161. data/lib/mongoid/scoping.rb +0 -356
  1162. data/lib/mongoid/serialization.rb +0 -161
  1163. data/lib/mongoid/sessions/factory.rb +0 -129
  1164. data/lib/mongoid/sessions/mongo_uri.rb +0 -93
  1165. data/lib/mongoid/sessions/validators/storage.rb +0 -49
  1166. data/lib/mongoid/sessions/validators.rb +0 -2
  1167. data/lib/mongoid/sessions.rb +0 -433
  1168. data/lib/mongoid/sharding.rb +0 -61
  1169. data/lib/mongoid/state.rb +0 -97
  1170. data/lib/mongoid/unit_of_work.rb +0 -61
  1171. data/lib/mongoid/validations/associated.rb +0 -46
  1172. data/lib/mongoid/validations/format.rb +0 -20
  1173. data/lib/mongoid/validations/length.rb +0 -20
  1174. data/lib/mongoid/validations/localizable.rb +0 -30
  1175. data/lib/mongoid/validations/macros.rb +0 -93
  1176. data/lib/mongoid/validations/presence.rb +0 -86
  1177. data/lib/mongoid/validations/queryable.rb +0 -31
  1178. data/lib/mongoid/validations/uniqueness.rb +0 -330
  1179. data/lib/mongoid/validations.rb +0 -166
  1180. data/lib/mongoid/versioning.rb +0 -217
  1181. data/lib/rack/mongoid/middleware/identity_map.rb +0 -39
  1182. data/lib/rack/mongoid.rb +0 -2
  1183. data/lib/rails/generators/mongoid/observer/observer_generator.rb +0 -17
  1184. data/lib/rails/generators/mongoid/observer/templates/observer.rb.tt +0 -4
  1185. data/lib/support/ruby_version.rb +0 -26
  1186. data/spec/app/models/account.rb +0 -32
  1187. data/spec/app/models/acolyte.rb +0 -16
  1188. data/spec/app/models/actor.rb +0 -19
  1189. data/spec/app/models/actor_observer.rb +0 -15
  1190. data/spec/app/models/actress.rb +0 -2
  1191. data/spec/app/models/address.rb +0 -72
  1192. data/spec/app/models/address_component.rb +0 -5
  1193. data/spec/app/models/address_number.rb +0 -6
  1194. data/spec/app/models/agency.rb +0 -5
  1195. data/spec/app/models/agent.rb +0 -12
  1196. data/spec/app/models/album.rb +0 -14
  1197. data/spec/app/models/alert.rb +0 -5
  1198. data/spec/app/models/animal.rb +0 -25
  1199. data/spec/app/models/answer.rb +0 -4
  1200. data/spec/app/models/appointment.rb +0 -7
  1201. data/spec/app/models/article.rb +0 -13
  1202. data/spec/app/models/artist.rb +0 -66
  1203. data/spec/app/models/artwork.rb +0 -4
  1204. data/spec/app/models/augmentation.rb +0 -11
  1205. data/spec/app/models/author.rb +0 -6
  1206. data/spec/app/models/band.rb +0 -25
  1207. data/spec/app/models/bar.rb +0 -9
  1208. data/spec/app/models/basic.rb +0 -6
  1209. data/spec/app/models/bed.rb +0 -1
  1210. data/spec/app/models/big_palette.rb +0 -2
  1211. data/spec/app/models/birthday.rb +0 -13
  1212. data/spec/app/models/book.rb +0 -12
  1213. data/spec/app/models/breed.rb +0 -4
  1214. data/spec/app/models/browser.rb +0 -6
  1215. data/spec/app/models/building.rb +0 -7
  1216. data/spec/app/models/building_address.rb +0 -7
  1217. data/spec/app/models/bus.rb +0 -7
  1218. data/spec/app/models/business.rb +0 -5
  1219. data/spec/app/models/callback_recorder.rb +0 -25
  1220. data/spec/app/models/callback_test.rb +0 -9
  1221. data/spec/app/models/canvas.rb +0 -25
  1222. data/spec/app/models/car.rb +0 -1
  1223. data/spec/app/models/cat.rb +0 -8
  1224. data/spec/app/models/category.rb +0 -8
  1225. data/spec/app/models/child.rb +0 -4
  1226. data/spec/app/models/child_doc.rb +0 -22
  1227. data/spec/app/models/church.rb +0 -4
  1228. data/spec/app/models/circle.rb +0 -3
  1229. data/spec/app/models/circuit.rb +0 -4
  1230. data/spec/app/models/circus.rb +0 -7
  1231. data/spec/app/models/code.rb +0 -5
  1232. data/spec/app/models/comment.rb +0 -16
  1233. data/spec/app/models/contractor.rb +0 -7
  1234. data/spec/app/models/cookie.rb +0 -6
  1235. data/spec/app/models/country_code.rb +0 -8
  1236. data/spec/app/models/definition.rb +0 -8
  1237. data/spec/app/models/description.rb +0 -11
  1238. data/spec/app/models/dictionary.rb +0 -10
  1239. data/spec/app/models/division.rb +0 -10
  1240. data/spec/app/models/doctor.rb +0 -12
  1241. data/spec/app/models/dog.rb +0 -7
  1242. data/spec/app/models/dokument.rb +0 -5
  1243. data/spec/app/models/driver.rb +0 -7
  1244. data/spec/app/models/drug.rb +0 -8
  1245. data/spec/app/models/email.rb +0 -6
  1246. data/spec/app/models/employer.rb +0 -5
  1247. data/spec/app/models/entry.rb +0 -6
  1248. data/spec/app/models/eraser.rb +0 -1
  1249. data/spec/app/models/event.rb +0 -22
  1250. data/spec/app/models/exhibition.rb +0 -4
  1251. data/spec/app/models/exhibitor.rb +0 -5
  1252. data/spec/app/models/eye.rb +0 -9
  1253. data/spec/app/models/eye_bowl.rb +0 -9
  1254. data/spec/app/models/face.rb +0 -8
  1255. data/spec/app/models/favorite.rb +0 -6
  1256. data/spec/app/models/filesystem.rb +0 -4
  1257. data/spec/app/models/fire_hydrant.rb +0 -6
  1258. data/spec/app/models/firefox.rb +0 -4
  1259. data/spec/app/models/fish.rb +0 -8
  1260. data/spec/app/models/folder.rb +0 -7
  1261. data/spec/app/models/folder_item.rb +0 -9
  1262. data/spec/app/models/fruits.rb +0 -28
  1263. data/spec/app/models/game.rb +0 -21
  1264. data/spec/app/models/ghost.rb +0 -7
  1265. data/spec/app/models/home.rb +0 -4
  1266. data/spec/app/models/house.rb +0 -8
  1267. data/spec/app/models/html_writer.rb +0 -3
  1268. data/spec/app/models/image.rb +0 -22
  1269. data/spec/app/models/implant.rb +0 -16
  1270. data/spec/app/models/item.rb +0 -12
  1271. data/spec/app/models/jar.rb +0 -7
  1272. data/spec/app/models/label.rb +0 -40
  1273. data/spec/app/models/language.rb +0 -5
  1274. data/spec/app/models/lat_lng.rb +0 -15
  1275. data/spec/app/models/league.rb +0 -11
  1276. data/spec/app/models/learner.rb +0 -2
  1277. data/spec/app/models/line_item.rb +0 -6
  1278. data/spec/app/models/location.rb +0 -8
  1279. data/spec/app/models/login.rb +0 -8
  1280. data/spec/app/models/manufacturer.rb +0 -7
  1281. data/spec/app/models/meat.rb +0 -4
  1282. data/spec/app/models/membership.rb +0 -4
  1283. data/spec/app/models/mixed_drink.rb +0 -4
  1284. data/spec/app/models/movie.rb +0 -12
  1285. data/spec/app/models/my_hash.rb +0 -2
  1286. data/spec/app/models/name.rb +0 -23
  1287. data/spec/app/models/node.rb +0 -5
  1288. data/spec/app/models/note.rb +0 -12
  1289. data/spec/app/models/ordered_post.rb +0 -6
  1290. data/spec/app/models/ordered_preference.rb +0 -6
  1291. data/spec/app/models/oscar.rb +0 -15
  1292. data/spec/app/models/override.rb +0 -16
  1293. data/spec/app/models/ownable.rb +0 -6
  1294. data/spec/app/models/owner.rb +0 -6
  1295. data/spec/app/models/pack.rb +0 -3
  1296. data/spec/app/models/page.rb +0 -5
  1297. data/spec/app/models/page_question.rb +0 -4
  1298. data/spec/app/models/palette.rb +0 -7
  1299. data/spec/app/models/paranoid_phone.rb +0 -25
  1300. data/spec/app/models/paranoid_post.rb +0 -36
  1301. data/spec/app/models/parent.rb +0 -5
  1302. data/spec/app/models/parent_doc.rb +0 -6
  1303. data/spec/app/models/passport.rb +0 -5
  1304. data/spec/app/models/patient.rb +0 -9
  1305. data/spec/app/models/pdf_writer.rb +0 -3
  1306. data/spec/app/models/pencil.rb +0 -1
  1307. data/spec/app/models/person.rb +0 -201
  1308. data/spec/app/models/pet.rb +0 -23
  1309. data/spec/app/models/pet_owner.rb +0 -6
  1310. data/spec/app/models/phone.rb +0 -11
  1311. data/spec/app/models/phone_observer.rb +0 -6
  1312. data/spec/app/models/pizza.rb +0 -7
  1313. data/spec/app/models/player.rb +0 -35
  1314. data/spec/app/models/post.rb +0 -43
  1315. data/spec/app/models/powerup.rb +0 -11
  1316. data/spec/app/models/preference.rb +0 -9
  1317. data/spec/app/models/princess.rb +0 -8
  1318. data/spec/app/models/product.rb +0 -17
  1319. data/spec/app/models/profile.rb +0 -5
  1320. data/spec/app/models/pronunciation.rb +0 -5
  1321. data/spec/app/models/purchase.rb +0 -4
  1322. data/spec/app/models/question.rb +0 -8
  1323. data/spec/app/models/quiz.rb +0 -10
  1324. data/spec/app/models/rating.rb +0 -8
  1325. data/spec/app/models/record.rb +0 -46
  1326. data/spec/app/models/registry.rb +0 -4
  1327. data/spec/app/models/role.rb +0 -7
  1328. data/spec/app/models/root_category.rb +0 -4
  1329. data/spec/app/models/sandwich.rb +0 -4
  1330. data/spec/app/models/scheduler.rb +0 -7
  1331. data/spec/app/models/seo.rb +0 -7
  1332. data/spec/app/models/series.rb +0 -4
  1333. data/spec/app/models/server.rb +0 -13
  1334. data/spec/app/models/service.rb +0 -22
  1335. data/spec/app/models/shape.rb +0 -12
  1336. data/spec/app/models/shelf.rb +0 -5
  1337. data/spec/app/models/shipping_container.rb +0 -5
  1338. data/spec/app/models/shipping_pack.rb +0 -3
  1339. data/spec/app/models/shop.rb +0 -6
  1340. data/spec/app/models/short_agent.rb +0 -4
  1341. data/spec/app/models/short_quiz.rb +0 -5
  1342. data/spec/app/models/slave.rb +0 -6
  1343. data/spec/app/models/song.rb +0 -8
  1344. data/spec/app/models/square.rb +0 -4
  1345. data/spec/app/models/strategy.rb +0 -3
  1346. data/spec/app/models/sub_item.rb +0 -3
  1347. data/spec/app/models/subscription.rb +0 -4
  1348. data/spec/app/models/survey.rb +0 -5
  1349. data/spec/app/models/symptom.rb +0 -6
  1350. data/spec/app/models/tag.rb +0 -8
  1351. data/spec/app/models/target.rb +0 -5
  1352. data/spec/app/models/template.rb +0 -5
  1353. data/spec/app/models/thing.rb +0 -9
  1354. data/spec/app/models/title.rb +0 -4
  1355. data/spec/app/models/tool.rb +0 -8
  1356. data/spec/app/models/topping.rb +0 -5
  1357. data/spec/app/models/track.rb +0 -38
  1358. data/spec/app/models/translation.rb +0 -5
  1359. data/spec/app/models/tree.rb +0 -9
  1360. data/spec/app/models/truck.rb +0 -3
  1361. data/spec/app/models/user.rb +0 -21
  1362. data/spec/app/models/user_account.rb +0 -10
  1363. data/spec/app/models/validation_callback.rb +0 -10
  1364. data/spec/app/models/vehicle.rb +0 -11
  1365. data/spec/app/models/version.rb +0 -5
  1366. data/spec/app/models/vet_visit.rb +0 -5
  1367. data/spec/app/models/video.rb +0 -17
  1368. data/spec/app/models/video_game.rb +0 -1
  1369. data/spec/app/models/weapon.rb +0 -11
  1370. data/spec/app/models/wiki_page.rb +0 -17
  1371. data/spec/app/models/word.rb +0 -12
  1372. data/spec/app/models/word_origin.rb +0 -11
  1373. data/spec/app/models/writer.rb +0 -11
  1374. data/spec/mongoid/atomic/positionable_spec.rb +0 -227
  1375. data/spec/mongoid/attributes/processing_spec.rb +0 -149
  1376. data/spec/mongoid/callbacks_spec.rb +0 -1564
  1377. data/spec/mongoid/components_spec.rb +0 -24
  1378. data/spec/mongoid/contextual/find_and_modify_spec.rb +0 -220
  1379. data/spec/mongoid/criterion/destructive_spec.rb +0 -101
  1380. data/spec/mongoid/criterion/inspection_spec.rb +0 -27
  1381. data/spec/mongoid/criterion/marshalable_spec.rb +0 -28
  1382. data/spec/mongoid/criterion/modifiable_spec.rb +0 -409
  1383. data/spec/mongoid/criterion/modification_spec.rb +0 -402
  1384. data/spec/mongoid/criterion/scoping_spec.rb +0 -391
  1385. data/spec/mongoid/dirty_spec.rb +0 -1508
  1386. data/spec/mongoid/errors/eager_load_spec.rb +0 -29
  1387. data/spec/mongoid/errors/mixed_session_configuration_spec.rb +0 -29
  1388. data/spec/mongoid/errors/no_session_config_spec.rb +0 -29
  1389. data/spec/mongoid/errors/no_session_database_spec.rb +0 -29
  1390. data/spec/mongoid/errors/no_session_hosts_spec.rb +0 -29
  1391. data/spec/mongoid/errors/no_sessions_config_spec.rb +0 -29
  1392. data/spec/mongoid/errors/versioning_not_on_root_spec.rb +0 -29
  1393. data/spec/mongoid/fields/internal/foreign_keys/array_spec.rb +0 -184
  1394. data/spec/mongoid/fields/internal/foreign_keys/object_spec.rb +0 -201
  1395. data/spec/mongoid/finders_spec.rb +0 -321
  1396. data/spec/mongoid/hierarchy_spec.rb +0 -244
  1397. data/spec/mongoid/identity_map_spec.rb +0 -564
  1398. data/spec/mongoid/indexes_spec.rb +0 -404
  1399. data/spec/mongoid/inspection_spec.rb +0 -57
  1400. data/spec/mongoid/json_spec.rb +0 -33
  1401. data/spec/mongoid/matchers/all_spec.rb +0 -31
  1402. data/spec/mongoid/matchers/and_spec.rb +0 -162
  1403. data/spec/mongoid/matchers/default_spec.rb +0 -130
  1404. data/spec/mongoid/matchers/exists_spec.rb +0 -57
  1405. data/spec/mongoid/matchers/gt_spec.rb +0 -74
  1406. data/spec/mongoid/matchers/gte_spec.rb +0 -74
  1407. data/spec/mongoid/matchers/in_spec.rb +0 -25
  1408. data/spec/mongoid/matchers/lt_spec.rb +0 -74
  1409. data/spec/mongoid/matchers/lte_spec.rb +0 -74
  1410. data/spec/mongoid/matchers/ne_spec.rb +0 -25
  1411. data/spec/mongoid/matchers/nin_spec.rb +0 -25
  1412. data/spec/mongoid/matchers/or_spec.rb +0 -106
  1413. data/spec/mongoid/matchers/size_spec.rb +0 -25
  1414. data/spec/mongoid/matchers_spec.rb +0 -532
  1415. data/spec/mongoid/multi_parameter_attributes_spec.rb +0 -128
  1416. data/spec/mongoid/nested_attributes_spec.rb +0 -4945
  1417. data/spec/mongoid/observer_spec.rb +0 -290
  1418. data/spec/mongoid/paranoia_spec.rb +0 -759
  1419. data/spec/mongoid/persistence/atomic/add_to_set_spec.rb +0 -262
  1420. data/spec/mongoid/persistence/atomic/bit_spec.rb +0 -88
  1421. data/spec/mongoid/persistence/atomic/inc_spec.rb +0 -133
  1422. data/spec/mongoid/persistence/atomic/pop_spec.rb +0 -111
  1423. data/spec/mongoid/persistence/atomic/pull_all_spec.rb +0 -77
  1424. data/spec/mongoid/persistence/atomic/pull_spec.rb +0 -80
  1425. data/spec/mongoid/persistence/atomic/push_all_spec.rb +0 -77
  1426. data/spec/mongoid/persistence/atomic/push_spec.rb +0 -77
  1427. data/spec/mongoid/persistence/atomic/rename_spec.rb +0 -42
  1428. data/spec/mongoid/persistence/atomic/sets_spec.rb +0 -154
  1429. data/spec/mongoid/persistence/atomic/unset_spec.rb +0 -65
  1430. data/spec/mongoid/persistence/atomic_spec.rb +0 -216
  1431. data/spec/mongoid/persistence/operations/embedded/insert_spec.rb +0 -191
  1432. data/spec/mongoid/persistence/operations/embedded/remove_spec.rb +0 -8
  1433. data/spec/mongoid/persistence/operations/insert_spec.rb +0 -149
  1434. data/spec/mongoid/persistence/operations/remove_spec.rb +0 -113
  1435. data/spec/mongoid/persistence/operations/update_spec.rb +0 -141
  1436. data/spec/mongoid/persistence/operations/upsert_spec.rb +0 -59
  1437. data/spec/mongoid/persistence/operations_spec.rb +0 -313
  1438. data/spec/mongoid/persistence_spec.rb +0 -2279
  1439. data/spec/mongoid/railties/document_spec.rb +0 -24
  1440. data/spec/mongoid/relations/accessors_spec.rb +0 -844
  1441. data/spec/mongoid/relations/auto_save_spec.rb +0 -261
  1442. data/spec/mongoid/relations/bindings/embedded/in_spec.rb +0 -171
  1443. data/spec/mongoid/relations/bindings/embedded/many_spec.rb +0 -54
  1444. data/spec/mongoid/relations/bindings/embedded/one_spec.rb +0 -77
  1445. data/spec/mongoid/relations/bindings/referenced/in_spec.rb +0 -241
  1446. data/spec/mongoid/relations/bindings/referenced/many_spec.rb +0 -153
  1447. data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +0 -178
  1448. data/spec/mongoid/relations/bindings/referenced/one_spec.rb +0 -131
  1449. data/spec/mongoid/relations/builders/embedded/in_spec.rb +0 -34
  1450. data/spec/mongoid/relations/builders/embedded/many_spec.rb +0 -132
  1451. data/spec/mongoid/relations/builders/embedded/one_spec.rb +0 -99
  1452. data/spec/mongoid/relations/builders/nested_attributes/many_spec.rb +0 -234
  1453. data/spec/mongoid/relations/builders/nested_attributes/one_spec.rb +0 -250
  1454. data/spec/mongoid/relations/builders/referenced/in_spec.rb +0 -241
  1455. data/spec/mongoid/relations/builders/referenced/many_spec.rb +0 -137
  1456. data/spec/mongoid/relations/builders/referenced/many_to_many_spec.rb +0 -178
  1457. data/spec/mongoid/relations/builders/referenced/one_spec.rb +0 -124
  1458. data/spec/mongoid/relations/builders_spec.rb +0 -226
  1459. data/spec/mongoid/relations/cascading/delete_spec.rb +0 -101
  1460. data/spec/mongoid/relations/cascading/destroy_spec.rb +0 -47
  1461. data/spec/mongoid/relations/cascading/nullify_spec.rb +0 -32
  1462. data/spec/mongoid/relations/cascading/restrict_spec.rb +0 -68
  1463. data/spec/mongoid/relations/cascading_spec.rb +0 -355
  1464. data/spec/mongoid/relations/constraint_spec.rb +0 -74
  1465. data/spec/mongoid/relations/conversions_spec.rb +0 -126
  1466. data/spec/mongoid/relations/counter_cache_spec.rb +0 -205
  1467. data/spec/mongoid/relations/cyclic_spec.rb +0 -156
  1468. data/spec/mongoid/relations/embedded/dirty_spec.rb +0 -65
  1469. data/spec/mongoid/relations/embedded/in_spec.rb +0 -580
  1470. data/spec/mongoid/relations/embedded/many_spec.rb +0 -3841
  1471. data/spec/mongoid/relations/embedded/one_spec.rb +0 -1055
  1472. data/spec/mongoid/relations/macros_spec.rb +0 -625
  1473. data/spec/mongoid/relations/metadata_spec.rb +0 -2030
  1474. data/spec/mongoid/relations/options_spec.rb +0 -35
  1475. data/spec/mongoid/relations/polymorphic_spec.rb +0 -132
  1476. data/spec/mongoid/relations/referenced/in_spec.rb +0 -1501
  1477. data/spec/mongoid/relations/referenced/many_spec.rb +0 -3632
  1478. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +0 -3561
  1479. data/spec/mongoid/relations/referenced/one_spec.rb +0 -1331
  1480. data/spec/mongoid/relations/reflections_spec.rb +0 -101
  1481. data/spec/mongoid/relations/synchronization_spec.rb +0 -453
  1482. data/spec/mongoid/relations/targets/enumerable_spec.rb +0 -1710
  1483. data/spec/mongoid/relations_spec.rb +0 -188
  1484. data/spec/mongoid/reloading_spec.rb +0 -305
  1485. data/spec/mongoid/scoping_spec.rb +0 -978
  1486. data/spec/mongoid/serialization_spec.rb +0 -833
  1487. data/spec/mongoid/sessions/factory_spec.rb +0 -312
  1488. data/spec/mongoid/sessions/mongo_uri_spec.rb +0 -103
  1489. data/spec/mongoid/sessions_spec.rb +0 -1111
  1490. data/spec/mongoid/sharding_spec.rb +0 -61
  1491. data/spec/mongoid/state_spec.rb +0 -102
  1492. data/spec/mongoid/unit_of_work_spec.rb +0 -196
  1493. data/spec/mongoid/validations/associated_spec.rb +0 -183
  1494. data/spec/mongoid/validations/format_spec.rb +0 -83
  1495. data/spec/mongoid/validations/length_spec.rb +0 -223
  1496. data/spec/mongoid/validations/numericality_spec.rb +0 -30
  1497. data/spec/mongoid/validations/presence_spec.rb +0 -592
  1498. data/spec/mongoid/validations/uniqueness_spec.rb +0 -2399
  1499. data/spec/mongoid/validations_spec.rb +0 -309
  1500. data/spec/mongoid/versioning_spec.rb +0 -540
  1501. data/spec/rack/mongoid/middleware/identity_map_spec.rb +0 -72
@@ -0,0 +1,4161 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ describe Mongoid::Association::Referenced::HasMany::Proxy do
6
+
7
+ before :all do
8
+ Mongoid.raise_not_found_error = true
9
+
10
+ Drug.belongs_to :person, primary_key: :username
11
+ Person.has_many :drugs, validate: false, primary_key: :username
12
+ end
13
+
14
+ after :all do
15
+ Drug.belongs_to :person, counter_cache: true
16
+ Person.has_many :drugs, validate: false
17
+ end
18
+
19
+ [ :<<, :push ].each do |method|
20
+
21
+ describe "##{method}" do
22
+
23
+ context "when providing the base class in child constructor" do
24
+
25
+ let(:person) do
26
+ Person.create!
27
+ end
28
+
29
+ let!(:post) do
30
+ person.posts.send(method, Post.new(person: person))
31
+ end
32
+
33
+ it "only adds the association once" do
34
+ expect(person.posts.size).to eq(1)
35
+ end
36
+
37
+ it "only persists the association once" do
38
+ expect(person.reload.posts.size).to eq(1)
39
+ end
40
+ end
41
+
42
+ context "when the associations are not polymorphic" do
43
+
44
+ context "when the parent is a new record" do
45
+
46
+ let(:person) do
47
+ Person.new
48
+ end
49
+
50
+ context "when the child is new" do
51
+
52
+ let(:post) do
53
+ Post.new
54
+ end
55
+
56
+ let!(:added) do
57
+ person.posts.send(method, post)
58
+ end
59
+
60
+ it "sets the foreign key on the association" do
61
+ expect(post.person_id).to eq(person.id)
62
+ end
63
+
64
+ it "sets the base on the inverse association" do
65
+ expect(post.person).to eq(person)
66
+ end
67
+
68
+ it "sets the same instance on the inverse association" do
69
+ expect(post.person).to eql(person)
70
+ end
71
+
72
+ it "does not save the target" do
73
+ expect(post).to be_new_record
74
+ end
75
+
76
+ it "adds the document to the target" do
77
+ expect(person.posts.size).to eq(1)
78
+ end
79
+
80
+ it "returns the association" do
81
+ expect(added).to eq(person.posts)
82
+ end
83
+ end
84
+
85
+ context "when the child is persisted" do
86
+
87
+ let(:post) do
88
+ Post.create!
89
+ end
90
+
91
+ before do
92
+ person.posts.send(method, post)
93
+ end
94
+
95
+ it "sets the foreign key on the association" do
96
+ expect(post.person_id).to eq(person.id)
97
+ end
98
+
99
+ it "sets the base on the inverse association" do
100
+ expect(post.person).to eq(person)
101
+ end
102
+
103
+ it "sets the same instance on the inverse association" do
104
+ expect(post.person).to eql(person)
105
+ end
106
+
107
+ it "does not save the parent" do
108
+ expect(person).to be_new_record
109
+ end
110
+
111
+ it "adds the document to the target" do
112
+ expect(person.posts.size).to eq(1)
113
+ end
114
+
115
+ context "when subsequently saving the parent" do
116
+
117
+ before do
118
+ person.save!
119
+ post.save!
120
+ end
121
+
122
+ it "returns the correct count of the association" do
123
+ expect(person.posts.count).to eq(1)
124
+ end
125
+ end
126
+ end
127
+ end
128
+
129
+ context "when appending in a parent create block" do
130
+
131
+ let!(:post) do
132
+ Post.create!(title: "testing")
133
+ end
134
+
135
+ let!(:person) do
136
+ Person.create! do |doc|
137
+ doc.posts << post
138
+ end
139
+ end
140
+
141
+ it "adds the documents to the association" do
142
+ expect(person.posts).to eq([ post ])
143
+ end
144
+
145
+ it "sets the foreign key on the inverse association" do
146
+ expect(post.person_id).to eq(person.id)
147
+ end
148
+
149
+ it "saves the target" do
150
+ expect(post).to be_persisted
151
+ end
152
+
153
+ it "adds the correct number of documents" do
154
+ expect(person.posts.size).to eq(1)
155
+ end
156
+
157
+ it "persists the link" do
158
+ expect(person.reload.posts).to eq([ post ])
159
+ end
160
+ end
161
+
162
+ context "when the parent is not a new record" do
163
+
164
+ let(:person) do
165
+ Person.create!
166
+ end
167
+
168
+ let(:post) do
169
+ Post.new
170
+ end
171
+
172
+ before do
173
+ person.posts.send(method, post)
174
+ end
175
+
176
+ it "sets the foreign key on the association" do
177
+ expect(post.person_id).to eq(person.id)
178
+ end
179
+
180
+ it "sets the base on the inverse association" do
181
+ expect(post.person).to eq(person)
182
+ end
183
+
184
+ it "sets the same instance on the inverse association" do
185
+ expect(post.person).to eql(person)
186
+ end
187
+
188
+ it "saves the target" do
189
+ expect(post).to be_persisted
190
+ end
191
+
192
+ it "adds the document to the target" do
193
+ expect(person.posts.count).to eq(1)
194
+ end
195
+
196
+ it "increments the counter cache" do
197
+ expect(person[:posts_count]).to eq(1)
198
+ expect(person.posts_count).to eq(1)
199
+ end
200
+
201
+ it "doesnt change the list of changes" do
202
+ expect(person.changed).to eq([])
203
+ end
204
+
205
+ context "when the related item has embedded associations" do
206
+
207
+ let!(:user) do
208
+ User.create!
209
+ end
210
+
211
+ before do
212
+ p = Post.create!(roles: [ Role.create! ])
213
+ user.posts = [ p ]
214
+ user.save!
215
+ end
216
+
217
+ it "add the document to the target" do
218
+ expect(user.posts.size).to eq(1)
219
+ expect(user.posts.first.roles.size).to eq(1)
220
+ end
221
+ end
222
+
223
+ context "when saving another post" do
224
+
225
+ before do
226
+ person.posts.send(method, Post.new)
227
+ end
228
+
229
+ it "increments the counter cache" do
230
+ expect(person.posts_count).to eq(2)
231
+ end
232
+ end
233
+
234
+ context "when documents already exist on the association" do
235
+
236
+ let(:post_two) do
237
+ Post.new(title: "Test")
238
+ end
239
+
240
+ before do
241
+ person.posts.send(method, post_two)
242
+ end
243
+
244
+ it "sets the foreign key on the association" do
245
+ expect(post_two.person_id).to eq(person.id)
246
+ end
247
+
248
+ it "sets the base on the inverse association" do
249
+ expect(post_two.person).to eq(person)
250
+ end
251
+
252
+ it "sets the same instance on the inverse association" do
253
+ expect(post_two.person).to eql(person)
254
+ end
255
+
256
+ it "saves the target" do
257
+ expect(post_two).to be_persisted
258
+ end
259
+
260
+ it "adds the document to the target" do
261
+ expect(person.posts.count).to eq(2)
262
+ end
263
+
264
+ it "increments the counter cache" do
265
+ expect(person.reload.posts_count).to eq(2)
266
+ end
267
+
268
+ it "contains the initial document in the target" do
269
+ expect(person.posts).to include(post)
270
+ end
271
+
272
+ it "contains the added document in the target" do
273
+ expect(person.posts).to include(post_two)
274
+ end
275
+ end
276
+ end
277
+ end
278
+
279
+ context "when.adding to the association" do
280
+
281
+ let(:person) do
282
+ Person.create!
283
+ end
284
+
285
+ context "when the operation succeeds" do
286
+
287
+ let(:post) do
288
+ Post.new
289
+ end
290
+
291
+ before do
292
+ person.posts.send(method, post)
293
+ end
294
+
295
+ it "adds the document to the association" do
296
+ expect(person.posts).to eq([ post ])
297
+ end
298
+ end
299
+
300
+ context "when the operation fails" do
301
+
302
+ let!(:existing) do
303
+ Post.create!
304
+ end
305
+
306
+ let(:post) do
307
+ Post.new do |doc|
308
+ doc._id = existing.id
309
+ end
310
+ end
311
+
312
+ it "raises an error" do
313
+ expect {
314
+ person.posts.send(method, post)
315
+ }.to raise_error(Mongo::Error::OperationFailure)
316
+ end
317
+ end
318
+ end
319
+
320
+ context "when the associations are polymorphic" do
321
+
322
+ context "when the parent is a new record" do
323
+
324
+ let(:movie) do
325
+ Movie.new
326
+ end
327
+
328
+ let(:rating) do
329
+ Rating.new
330
+ end
331
+
332
+ before do
333
+ movie.ratings.send(method, rating)
334
+ end
335
+
336
+ it "sets the foreign key on the association" do
337
+ expect(rating.ratable_id).to eq(movie.id)
338
+ end
339
+
340
+ it "sets the base on the inverse association" do
341
+ expect(rating.ratable).to eq(movie)
342
+ end
343
+
344
+ it "does not save the target" do
345
+ expect(rating).to be_new_record
346
+ end
347
+
348
+ it "adds the document to the target" do
349
+ expect(movie.ratings.size).to eq(1)
350
+ end
351
+ end
352
+
353
+ context "when the parent is not a new record" do
354
+
355
+ let(:movie) do
356
+ Movie.create!
357
+ end
358
+
359
+ let(:rating) do
360
+ Rating.new
361
+ end
362
+
363
+ before do
364
+ movie.ratings.send(method, rating)
365
+ end
366
+
367
+ it "sets the foreign key on the association" do
368
+ expect(rating.ratable_id).to eq(movie.id)
369
+ end
370
+
371
+ it "sets the base on the inverse association" do
372
+ expect(rating.ratable).to eq(movie)
373
+ end
374
+
375
+ it "saves the target" do
376
+ expect(rating).to be_persisted
377
+ end
378
+
379
+ it "adds the document to the target" do
380
+ expect(movie.ratings.count).to eq(1)
381
+ end
382
+ end
383
+ end
384
+ end
385
+ end
386
+
387
+ describe "#=" do
388
+
389
+ context "when the association is not polymorphic" do
390
+
391
+ context "when the parent is a new record" do
392
+
393
+ let(:person) do
394
+ Person.new
395
+ end
396
+
397
+ let(:post) do
398
+ Post.new
399
+ end
400
+
401
+ before do
402
+ person.posts = [ post ]
403
+ end
404
+
405
+ it "sets the target of the association" do
406
+ expect(person.posts._target).to eq([ post ])
407
+ end
408
+
409
+ it "sets the foreign key on the association" do
410
+ expect(post.person_id).to eq(person.id)
411
+ end
412
+
413
+ it "sets the base on the inverse association" do
414
+ expect(post.person).to eq(person)
415
+ end
416
+
417
+ it "does not save the target" do
418
+ expect(post).to_not be_persisted
419
+ end
420
+ end
421
+
422
+ context "when the parent is not a new record" do
423
+
424
+ let(:person) do
425
+ Person.create!
426
+ end
427
+
428
+ let(:post) do
429
+ Post.new
430
+ end
431
+
432
+ before do
433
+ person.posts = [ post ]
434
+ end
435
+
436
+ it "sets the target of the association" do
437
+ expect(person.posts._target).to eq([ post ])
438
+ end
439
+
440
+ it "sets the foreign key of the association" do
441
+ expect(post.person_id).to eq(person.id)
442
+ end
443
+
444
+ it "sets the base on the inverse association" do
445
+ expect(post.person).to eq(person)
446
+ end
447
+
448
+ it "saves the target" do
449
+ expect(post).to be_persisted
450
+ end
451
+
452
+ context "when replacing the association with the same documents" do
453
+
454
+ context "when using the same in memory instance" do
455
+
456
+ before do
457
+ person.posts = [ post ]
458
+ end
459
+
460
+ it "keeps the association intact" do
461
+ expect(person.posts).to eq([ post ])
462
+ end
463
+
464
+ it "does not delete the association" do
465
+ expect(person.reload.posts).to eq([ post ])
466
+ end
467
+ end
468
+
469
+ context "when using a new instance" do
470
+
471
+ let(:from_db) do
472
+ Person.find(person.id)
473
+ end
474
+
475
+ before do
476
+ from_db.posts = [ post ]
477
+ end
478
+
479
+ it "keeps the association intact" do
480
+ expect(from_db.posts).to eq([ post ])
481
+ end
482
+
483
+ it "does not delete the association" do
484
+ expect(from_db.reload.posts).to eq([ post ])
485
+ end
486
+ end
487
+ end
488
+
489
+ context "when replacing the with a combination of old and new docs" do
490
+
491
+ let(:new_post) do
492
+ Post.create!(title: "new post")
493
+ end
494
+
495
+ context "when using the same in memory instance" do
496
+
497
+ before do
498
+ person.posts = [ post, new_post ]
499
+ end
500
+
501
+ it "keeps the association intact" do
502
+ expect(person.posts.size).to eq(2)
503
+ end
504
+
505
+ it "keeps the first post" do
506
+ expect(person.posts).to include(post)
507
+ end
508
+
509
+ it "keeps the second post" do
510
+ expect(person.posts).to include(new_post)
511
+ end
512
+
513
+ it "does not delete the association" do
514
+ expect(person.reload.posts).to eq([ post, new_post ])
515
+ end
516
+ end
517
+
518
+ context "when using a new instance" do
519
+
520
+ let(:from_db) do
521
+ Person.find(person.id)
522
+ end
523
+
524
+ before do
525
+ from_db.posts = [ post, new_post ]
526
+ end
527
+
528
+ it "keeps the association intact" do
529
+ expect(from_db.posts).to eq([ post, new_post ])
530
+ end
531
+
532
+ it "does not delete the association" do
533
+ expect(from_db.reload.posts).to eq([ post, new_post ])
534
+ end
535
+ end
536
+ end
537
+
538
+ context "when replacing the with a combination of only new docs" do
539
+
540
+ let(:new_post) do
541
+ Post.create!(title: "new post")
542
+ end
543
+
544
+ context "when using the same in memory instance" do
545
+
546
+ before do
547
+ person.posts = [ new_post ]
548
+ end
549
+
550
+ it "keeps the association intact" do
551
+ expect(person.posts).to eq([ new_post ])
552
+ end
553
+
554
+ it "does not delete the association" do
555
+ expect(person.reload.posts).to eq([ new_post ])
556
+ end
557
+ end
558
+
559
+ context "when using a new instance" do
560
+
561
+ let(:from_db) do
562
+ Person.find(person.id)
563
+ end
564
+
565
+ before do
566
+ from_db.posts = [ new_post ]
567
+ end
568
+
569
+ it "keeps the association intact" do
570
+ expect(from_db.posts).to eq([ new_post ])
571
+ end
572
+
573
+ it "does not delete the association" do
574
+ expect(from_db.reload.posts).to eq([ new_post ])
575
+ end
576
+ end
577
+ end
578
+ end
579
+ end
580
+
581
+ context "when the association is polymorphic" do
582
+
583
+ context "when the parent is a new record" do
584
+
585
+ let(:movie) do
586
+ Movie.new
587
+ end
588
+
589
+ let(:rating) do
590
+ Rating.new
591
+ end
592
+
593
+ before do
594
+ movie.ratings = [ rating ]
595
+ end
596
+
597
+ it "sets the target of the association" do
598
+ expect(movie.ratings._target).to eq([ rating ])
599
+ end
600
+
601
+ it "sets the foreign key on the association" do
602
+ expect(rating.ratable_id).to eq(movie.id)
603
+ end
604
+
605
+ it "sets the base on the inverse association" do
606
+ expect(rating.ratable).to eq(movie)
607
+ end
608
+
609
+ it "does not save the target" do
610
+ expect(rating).to_not be_persisted
611
+ end
612
+ end
613
+
614
+ context "when the parent is not a new record" do
615
+
616
+ let(:movie) do
617
+ Movie.create!
618
+ end
619
+
620
+ let(:rating) do
621
+ Rating.new
622
+ end
623
+
624
+ before do
625
+ movie.ratings = [ rating ]
626
+ end
627
+
628
+ it "sets the target of the association" do
629
+ expect(movie.ratings._target).to eq([ rating ])
630
+ end
631
+
632
+ it "sets the foreign key of the association" do
633
+ expect(rating.ratable_id).to eq(movie.id)
634
+ end
635
+
636
+ it "sets the base on the inverse association" do
637
+ expect(rating.ratable).to eq(movie)
638
+ end
639
+
640
+ it "saves the target" do
641
+ expect(rating).to be_persisted
642
+ end
643
+ end
644
+ end
645
+ end
646
+
647
+ describe "#= []" do
648
+
649
+ context "when the parent is persisted" do
650
+
651
+ let(:posts) do
652
+ [ Post.create!(title: "1"), Post.create!(title: "2") ]
653
+ end
654
+
655
+ let(:person) do
656
+ Person.create!(posts: posts)
657
+ end
658
+
659
+ context "when the parent has multiple children" do
660
+
661
+ before do
662
+ person.posts = []
663
+ end
664
+
665
+ it "removes all the children" do
666
+ expect(person.posts).to be_empty
667
+ end
668
+
669
+ it "persists the changes" do
670
+ expect(person.posts(true)).to be_empty
671
+ end
672
+ end
673
+ end
674
+ end
675
+
676
+ describe "#= nil" do
677
+
678
+ context "when the association is not polymorphic" do
679
+
680
+ context "when the parent is a new record" do
681
+
682
+ let(:person) do
683
+ Person.new
684
+ end
685
+
686
+ let(:post) do
687
+ Post.new
688
+ end
689
+
690
+ before do
691
+ person.posts = [ post ]
692
+ person.posts = nil
693
+ end
694
+
695
+ it "sets the association to an empty array" do
696
+ expect(person.posts).to be_empty
697
+ end
698
+
699
+ it "removed the inverse association" do
700
+ expect(post.person).to be_nil
701
+ end
702
+
703
+ it "removes the foreign key value" do
704
+ expect(post.person_id).to be_nil
705
+ end
706
+ end
707
+
708
+ context "when the parent is not a new record" do
709
+
710
+ let(:person) do
711
+ Person.create!
712
+ end
713
+
714
+ context "when dependent is destructive" do
715
+
716
+ let(:post) do
717
+ Post.new
718
+ end
719
+
720
+ before do
721
+ person.posts = [ post ]
722
+ person.posts = nil
723
+ end
724
+
725
+ it "sets the association to empty" do
726
+ expect(person.posts).to be_empty
727
+ end
728
+
729
+ it "removed the inverse association" do
730
+ expect(post.person).to be_nil
731
+ end
732
+
733
+ it "removes the foreign key value" do
734
+ expect(post.person_id).to be_nil
735
+ end
736
+
737
+ it "deletes the target from the database" do
738
+ expect(post).to be_destroyed
739
+ end
740
+ end
741
+
742
+ context "when dependent is not destructive" do
743
+
744
+ let(:drug) do
745
+ Drug.new(name: "Oxycodone")
746
+ end
747
+
748
+ before do
749
+ person.drugs = [ drug ]
750
+ person.drugs = nil
751
+ end
752
+
753
+ it "sets the association to empty" do
754
+ expect(person.drugs).to be_empty
755
+ end
756
+
757
+ it "removed the inverse association" do
758
+ expect(drug.person).to be_nil
759
+ end
760
+
761
+ it "removes the foreign key value" do
762
+ expect(drug.person_id).to be_nil
763
+ end
764
+
765
+ it "nullifies the association" do
766
+ expect(drug).to_not be_destroyed
767
+ end
768
+ end
769
+ end
770
+ end
771
+
772
+ context "when the association is polymorphic" do
773
+
774
+ context "when the parent is a new record" do
775
+
776
+ let(:movie) do
777
+ Movie.new
778
+ end
779
+
780
+ let(:rating) do
781
+ Rating.new
782
+ end
783
+
784
+ before do
785
+ movie.ratings = [ rating ]
786
+ movie.ratings = nil
787
+ end
788
+
789
+ it "sets the association to an empty array" do
790
+ expect(movie.ratings).to be_empty
791
+ end
792
+
793
+ it "removed the inverse association" do
794
+ expect(rating.ratable).to be_nil
795
+ end
796
+
797
+ it "removes the foreign key value" do
798
+ expect(rating.ratable_id).to be_nil
799
+ end
800
+ end
801
+
802
+ context "when the parent is not a new record" do
803
+
804
+ let(:movie) do
805
+ Movie.create!
806
+ end
807
+
808
+ let(:rating) do
809
+ Rating.new
810
+ end
811
+
812
+ before do
813
+ movie.ratings = [ rating ]
814
+ movie.ratings = nil
815
+ end
816
+
817
+ it "sets the association to empty" do
818
+ expect(movie.ratings).to be_empty
819
+ end
820
+
821
+ it "removed the inverse association" do
822
+ expect(rating.ratable).to be_nil
823
+ end
824
+
825
+ it "removes the foreign key value" do
826
+ expect(rating.ratable_id).to be_nil
827
+ end
828
+
829
+ context "when dependent is nullify" do
830
+
831
+ it "does not delete the target from the database" do
832
+ expect(rating).to_not be_destroyed
833
+ end
834
+ end
835
+ end
836
+ end
837
+ end
838
+
839
+ describe "#\{name}_ids=" do
840
+
841
+ let(:person) do
842
+ Person.new
843
+ end
844
+
845
+ let(:post_one) do
846
+ Post.create!
847
+ end
848
+
849
+ let(:post_two) do
850
+ Post.create!
851
+ end
852
+
853
+ before do
854
+ person.post_ids = [ post_one.id, post_two.id ]
855
+ end
856
+
857
+ it "calls setter with documents find by given ids" do
858
+ expect(person.posts).to eq([ post_one, post_two ])
859
+ end
860
+ end
861
+
862
+ describe "#\{name}_ids" do
863
+
864
+ let(:posts) do
865
+ [ Post.create!, Post.create! ]
866
+ end
867
+
868
+ let(:person) do
869
+ Person.create!(posts: posts)
870
+ end
871
+
872
+ it "returns ids of documents that are in the association" do
873
+ expect(person.post_ids).to eq(posts.map(&:id))
874
+ end
875
+ end
876
+
877
+ [ :build, :new ].each do |method|
878
+
879
+ describe "##{method}" do
880
+
881
+ context "when the association is not polymorphic" do
882
+
883
+ context "when the parent is a new record" do
884
+
885
+ let(:person) do
886
+ Person.new(title: "sir")
887
+ end
888
+
889
+ let!(:post) do
890
+ person.posts.send(method, title: "$$$")
891
+ end
892
+
893
+ it "sets the foreign key on the association" do
894
+ expect(post.person_id).to eq(person.id)
895
+ end
896
+
897
+ it "sets the base on the inverse association" do
898
+ expect(post.person).to eq(person)
899
+ end
900
+
901
+ it "sets the attributes" do
902
+ expect(post.title).to eq("$$$")
903
+ end
904
+
905
+ it "sets the post processed defaults" do
906
+ expect(post.person_title).to eq(person.title)
907
+ end
908
+
909
+ it "does not save the target" do
910
+ expect(post).to be_new_record
911
+ end
912
+
913
+ it "adds the document to the target" do
914
+ expect(person.posts.size).to eq(1)
915
+ end
916
+
917
+ it "does not perform validation" do
918
+ expect(post.errors).to be_empty
919
+ end
920
+ end
921
+
922
+ context "when the parent is not a new record" do
923
+
924
+ let(:person) do
925
+ Person.create!
926
+ end
927
+
928
+ let!(:post) do
929
+ person.posts.send(method, text: "Testing")
930
+ end
931
+
932
+ it "sets the foreign key on the association" do
933
+ expect(post.person_id).to eq(person.id)
934
+ end
935
+
936
+ it "sets the base on the inverse association" do
937
+ expect(post.person).to eq(person)
938
+ end
939
+
940
+ it "sets the attributes" do
941
+ expect(post.text).to eq("Testing")
942
+ end
943
+
944
+ it "does not save the target" do
945
+ expect(post).to be_new_record
946
+ end
947
+
948
+ it "adds the document to the target" do
949
+ expect(person.posts.size).to eq(1)
950
+ end
951
+ end
952
+ end
953
+
954
+ context "when the association is polymorphic" do
955
+
956
+ context "when the parent is a subclass" do
957
+
958
+ let(:video_game) do
959
+ VideoGame.create!
960
+ end
961
+
962
+ let(:rating) do
963
+ video_game.ratings.build
964
+ end
965
+
966
+ it "sets the parent on the child" do
967
+ expect(rating.ratable).to eq(video_game)
968
+ end
969
+
970
+ it "sets the correct polymorphic type" do
971
+ expect(rating.ratable_type).to eq("VideoGame")
972
+ end
973
+ end
974
+
975
+ context "when the parent is a new record" do
976
+
977
+ let(:movie) do
978
+ Movie.new
979
+ end
980
+
981
+ let!(:rating) do
982
+ movie.ratings.send(method, value: 3)
983
+ end
984
+
985
+ it "sets the foreign key on the association" do
986
+ expect(rating.ratable_id).to eq(movie.id)
987
+ end
988
+
989
+ it "sets the base on the inverse association" do
990
+ expect(rating.ratable).to eq(movie)
991
+ end
992
+
993
+ it "sets the attributes" do
994
+ expect(rating.value).to eq(3)
995
+ end
996
+
997
+ it "does not save the target" do
998
+ expect(rating).to be_new_record
999
+ end
1000
+
1001
+ it "adds the document to the target" do
1002
+ expect(movie.ratings.size).to eq(1)
1003
+ end
1004
+
1005
+ it "does not perform validation" do
1006
+ expect(rating.errors).to be_empty
1007
+ end
1008
+ end
1009
+
1010
+ context "when the parent is not a new record" do
1011
+
1012
+ let(:movie) do
1013
+ Movie.create!
1014
+ end
1015
+
1016
+ let!(:rating) do
1017
+ movie.ratings.send(method, value: 4)
1018
+ end
1019
+
1020
+ it "sets the foreign key on the association" do
1021
+ expect(rating.ratable_id).to eq(movie.id)
1022
+ end
1023
+
1024
+ it "sets the base on the inverse association" do
1025
+ expect(rating.ratable).to eq(movie)
1026
+ end
1027
+
1028
+ it "sets the attributes" do
1029
+ expect(rating.value).to eq(4)
1030
+ end
1031
+
1032
+ it "does not save the target" do
1033
+ expect(rating).to be_new_record
1034
+ end
1035
+
1036
+ it "adds the document to the target" do
1037
+ expect(movie.ratings.size).to eq(1)
1038
+ end
1039
+ end
1040
+ end
1041
+ end
1042
+ end
1043
+
1044
+ describe "#clear" do
1045
+
1046
+ context "when the association is not polymorphic" do
1047
+
1048
+ context "when the parent has been persisted" do
1049
+
1050
+ let!(:person) do
1051
+ Person.create!
1052
+ end
1053
+
1054
+ context "when the children are persisted" do
1055
+
1056
+ let!(:post) do
1057
+ person.posts.create!(title: "Testing")
1058
+ end
1059
+
1060
+ let!(:association) do
1061
+ person.posts.clear
1062
+ end
1063
+
1064
+ it "clears out the association" do
1065
+ expect(person.posts).to be_empty
1066
+ end
1067
+
1068
+ it "marks the documents as deleted" do
1069
+ expect(post).to be_destroyed
1070
+ end
1071
+
1072
+ it "deletes the documents from the db" do
1073
+ expect(person.reload.posts).to be_empty
1074
+ end
1075
+
1076
+ it "returns the association" do
1077
+ expect(association).to be_empty
1078
+ end
1079
+ end
1080
+
1081
+ context "when the children are not persisted" do
1082
+
1083
+ let!(:post) do
1084
+ person.posts.build(title: "Testing")
1085
+ end
1086
+
1087
+ let!(:association) do
1088
+ person.posts.clear
1089
+ end
1090
+
1091
+ it "clears out the association" do
1092
+ expect(person.posts).to be_empty
1093
+ end
1094
+ end
1095
+ end
1096
+
1097
+ context "when the parent is not persisted" do
1098
+
1099
+ let(:person) do
1100
+ Person.new
1101
+ end
1102
+
1103
+ let!(:post) do
1104
+ person.posts.build(title: "Testing")
1105
+ end
1106
+
1107
+ let!(:association) do
1108
+ person.posts.clear
1109
+ end
1110
+
1111
+ it "clears out the association" do
1112
+ expect(person.posts).to be_empty
1113
+ end
1114
+ end
1115
+ end
1116
+
1117
+ context "when the association is polymorphic" do
1118
+
1119
+ context "when the parent has been persisted" do
1120
+
1121
+ let!(:movie) do
1122
+ Movie.create!
1123
+ end
1124
+
1125
+ context "when the children are persisted" do
1126
+
1127
+ let!(:rating) do
1128
+ movie.ratings.create!(value: 1)
1129
+ end
1130
+
1131
+ let!(:association) do
1132
+ movie.ratings.clear
1133
+ end
1134
+
1135
+ it "clears out the association" do
1136
+ expect(movie.ratings).to be_empty
1137
+ end
1138
+
1139
+ it "handles the proper dependent strategy" do
1140
+ expect(rating).to_not be_destroyed
1141
+ end
1142
+
1143
+ it "deletes the documents from the db" do
1144
+ expect(movie.reload.ratings).to be_empty
1145
+ end
1146
+
1147
+ it "returns the association" do
1148
+ expect(association).to be_empty
1149
+ end
1150
+ end
1151
+
1152
+ context "when the children are not persisted" do
1153
+
1154
+ let!(:rating) do
1155
+ movie.ratings.build(value: 3)
1156
+ end
1157
+
1158
+ let!(:association) do
1159
+ movie.ratings.clear
1160
+ end
1161
+
1162
+ it "clears out the association" do
1163
+ expect(movie.ratings).to be_empty
1164
+ end
1165
+ end
1166
+ end
1167
+
1168
+ context "when the parent is not persisted" do
1169
+
1170
+ let(:movie) do
1171
+ Movie.new
1172
+ end
1173
+
1174
+ let!(:rating) do
1175
+ movie.ratings.build(value: 2)
1176
+ end
1177
+
1178
+ let!(:association) do
1179
+ movie.ratings.clear
1180
+ end
1181
+
1182
+ it "clears out the association" do
1183
+ expect(movie.ratings).to be_empty
1184
+ end
1185
+ end
1186
+ end
1187
+ end
1188
+
1189
+ describe "#concat" do
1190
+
1191
+ context "when the associations are not polymorphic" do
1192
+
1193
+ context "when the parent is a new record" do
1194
+
1195
+ let(:person) do
1196
+ Person.new
1197
+ end
1198
+
1199
+ let(:post) do
1200
+ Post.new
1201
+ end
1202
+
1203
+ before do
1204
+ person.posts.concat([ post ])
1205
+ end
1206
+
1207
+ it "sets the foreign key on the association" do
1208
+ expect(post.person_id).to eq(person.id)
1209
+ end
1210
+
1211
+ it "sets the base on the inverse association" do
1212
+ expect(post.person).to eq(person)
1213
+ end
1214
+
1215
+ it "sets the same instance on the inverse association" do
1216
+ expect(post.person).to eql(person)
1217
+ end
1218
+
1219
+ it "does not save the target" do
1220
+ expect(post).to be_new_record
1221
+ end
1222
+
1223
+ it "adds the document to the target" do
1224
+ expect(person.posts.size).to eq(1)
1225
+ end
1226
+ end
1227
+
1228
+ context "when appending in a parent create block" do
1229
+
1230
+ let!(:post) do
1231
+ Post.create!(title: "testing")
1232
+ end
1233
+
1234
+ let!(:person) do
1235
+ Person.create! do |doc|
1236
+ doc.posts.concat([ post ])
1237
+ end
1238
+ end
1239
+
1240
+ it "adds the documents to the association" do
1241
+ expect(person.posts).to eq([ post ])
1242
+ end
1243
+
1244
+ it "sets the foreign key on the inverse association" do
1245
+ expect(post.person_id).to eq(person.id)
1246
+ end
1247
+
1248
+ it "saves the target" do
1249
+ expect(post).to be_persisted
1250
+ end
1251
+
1252
+ it "adds the correct number of documents" do
1253
+ expect(person.posts.size).to eq(1)
1254
+ end
1255
+
1256
+ it "persists the link" do
1257
+ expect(person.reload.posts).to eq([ post ])
1258
+ end
1259
+ end
1260
+
1261
+ context "when the parent is not a new record" do
1262
+
1263
+ let(:person) do
1264
+ Person.create!
1265
+ end
1266
+
1267
+ let(:post) do
1268
+ Post.new
1269
+ end
1270
+
1271
+ let(:post_three) do
1272
+ Post.new
1273
+ end
1274
+
1275
+ before do
1276
+ person.posts.concat([ post, post_three ])
1277
+ end
1278
+
1279
+ it "sets the foreign key on the association" do
1280
+ expect(post.person_id).to eq(person.id)
1281
+ end
1282
+
1283
+ it "sets the base on the inverse association" do
1284
+ expect(post.person).to eq(person)
1285
+ end
1286
+
1287
+ it "sets the same instance on the inverse association" do
1288
+ expect(post.person).to eql(person)
1289
+ end
1290
+
1291
+ it "saves the target" do
1292
+ expect(post).to be_persisted
1293
+ end
1294
+
1295
+ it "adds the document to the target" do
1296
+ expect(person.posts.count).to eq(2)
1297
+ end
1298
+
1299
+ context "when documents already exist on the association" do
1300
+
1301
+ let(:post_two) do
1302
+ Post.new(title: "Test")
1303
+ end
1304
+
1305
+ before do
1306
+ person.posts.concat([ post_two ])
1307
+ end
1308
+
1309
+ it "sets the foreign key on the association" do
1310
+ expect(post_two.person_id).to eq(person.id)
1311
+ end
1312
+
1313
+ it "sets the base on the inverse association" do
1314
+ expect(post_two.person).to eq(person)
1315
+ end
1316
+
1317
+ it "sets the same instance on the inverse association" do
1318
+ expect(post_two.person).to eql(person)
1319
+ end
1320
+
1321
+ it "saves the target" do
1322
+ expect(post_two).to be_persisted
1323
+ end
1324
+
1325
+ it "adds the document to the target" do
1326
+ expect(person.posts.count).to eq(3)
1327
+ end
1328
+
1329
+ it "contains the initial document in the target" do
1330
+ expect(person.posts).to include(post)
1331
+ end
1332
+
1333
+ it "contains the added document in the target" do
1334
+ expect(person.posts).to include(post_two)
1335
+ end
1336
+ end
1337
+ end
1338
+ end
1339
+ end
1340
+
1341
+ context "when the associations are polymorphic" do
1342
+
1343
+ context "when the parent is a new record" do
1344
+
1345
+ let(:movie) do
1346
+ Movie.new
1347
+ end
1348
+
1349
+ let(:rating) do
1350
+ Rating.new
1351
+ end
1352
+
1353
+ before do
1354
+ movie.ratings.concat([ rating ])
1355
+ end
1356
+
1357
+ it "sets the foreign key on the association" do
1358
+ expect(rating.ratable_id).to eq(movie.id)
1359
+ end
1360
+
1361
+ it "sets the base on the inverse association" do
1362
+ expect(rating.ratable).to eq(movie)
1363
+ end
1364
+
1365
+ it "does not save the target" do
1366
+ expect(rating).to be_new_record
1367
+ end
1368
+
1369
+ it "adds the document to the target" do
1370
+ expect(movie.ratings.size).to eq(1)
1371
+ end
1372
+ end
1373
+
1374
+ context "when the parent is not a new record" do
1375
+
1376
+ let(:movie) do
1377
+ Movie.create!
1378
+ end
1379
+
1380
+ let(:rating) do
1381
+ Rating.new
1382
+ end
1383
+
1384
+ before do
1385
+ movie.ratings.concat([ rating ])
1386
+ end
1387
+
1388
+ it "sets the foreign key on the association" do
1389
+ expect(rating.ratable_id).to eq(movie.id)
1390
+ end
1391
+
1392
+ it "sets the base on the inverse association" do
1393
+ expect(rating.ratable).to eq(movie)
1394
+ end
1395
+
1396
+ it "saves the target" do
1397
+ expect(rating).to be_persisted
1398
+ end
1399
+
1400
+ it "adds the document to the target" do
1401
+ expect(movie.ratings.count).to eq(1)
1402
+ end
1403
+ end
1404
+ end
1405
+
1406
+ describe "#count" do
1407
+
1408
+ let(:movie) do
1409
+ Movie.create!
1410
+ end
1411
+
1412
+ context "when documents have been persisted" do
1413
+
1414
+ let!(:rating) do
1415
+ movie.ratings.create!(value: 1)
1416
+ end
1417
+
1418
+ it "returns the number of persisted documents" do
1419
+ expect(movie.ratings.count).to eq(1)
1420
+ end
1421
+
1422
+ it "block form includes persisted results" do
1423
+ expect(movie.ratings.count {|r| r.value >= 1 }).to eq(1)
1424
+ expect(movie.ratings.count {|r| r.value >= 2 }).to eq(0)
1425
+ end
1426
+ end
1427
+
1428
+ context "when documents have not been persisted" do
1429
+
1430
+ let!(:rating) do
1431
+ movie.ratings.build(value: 1)
1432
+ end
1433
+
1434
+ it "returns 0" do
1435
+ expect(movie.ratings.count).to eq(0)
1436
+ end
1437
+
1438
+ it "block form does not include unpersisted results" do
1439
+ expect(movie.ratings.count {|r| r.value == 1 }).to eq(0)
1440
+ end
1441
+ end
1442
+
1443
+ context "when mixed persisted and unpersisted documents" do
1444
+
1445
+ before do
1446
+ movie.ratings.create(value: 1)
1447
+ movie.ratings.build(value: 2)
1448
+ end
1449
+
1450
+ it "returns 1" do
1451
+ expect(movie.ratings.count).to eq(1)
1452
+ end
1453
+
1454
+ it "block form includes only persisted results" do
1455
+ expect(movie.ratings.count {|r| r.value >= 1 }).to eq(1)
1456
+ expect(movie.ratings.count {|r| r.value == 2 }).to eq(0)
1457
+ end
1458
+ end
1459
+
1460
+ context "when no document is added" do
1461
+
1462
+ it "returns false" do
1463
+ expect(movie.ratings.any?).to be false
1464
+ end
1465
+ end
1466
+
1467
+ context "when new documents exist in the database" do
1468
+
1469
+ context "when the documents are part of the association" do
1470
+
1471
+ before do
1472
+ Rating.create!(ratable: movie)
1473
+ end
1474
+
1475
+ it "returns the count from the db" do
1476
+ expect(movie.ratings.count).to eq(1)
1477
+ end
1478
+ end
1479
+
1480
+ context "when the documents are not part of the association" do
1481
+
1482
+ before do
1483
+ Rating.create!
1484
+ end
1485
+
1486
+ it "returns the count from the db" do
1487
+ expect(movie.ratings.count).to eq(0)
1488
+ end
1489
+ end
1490
+ end
1491
+ end
1492
+
1493
+ describe "#any?" do
1494
+
1495
+ shared_examples 'does not query database when association is loaded' do
1496
+
1497
+ let(:fresh_movie) { Movie.find(movie.id) }
1498
+
1499
+ context 'when association is not loaded' do
1500
+ it 'queries database on each call' do
1501
+ fresh_movie
1502
+
1503
+ expect_query(1) do
1504
+ fresh_movie.ratings.any?.should be expected_result
1505
+ end
1506
+
1507
+ expect_query(1) do
1508
+ fresh_movie.ratings.any?.should be expected_result
1509
+ end
1510
+ end
1511
+
1512
+ context 'when using a block' do
1513
+ it 'queries database on first call only' do
1514
+ fresh_movie
1515
+
1516
+ expect_query(1) do
1517
+ fresh_movie.ratings.any? { false }.should be false
1518
+ end
1519
+
1520
+ expect_no_queries do
1521
+ fresh_movie.ratings.any? { false }.should be false
1522
+ end
1523
+ end
1524
+ end
1525
+ end
1526
+
1527
+ context 'when association is loaded' do
1528
+ it 'does not query database' do
1529
+ fresh_movie
1530
+
1531
+ expect_query(1) do
1532
+ fresh_movie.ratings.any?.should be expected_result
1533
+ end
1534
+
1535
+ fresh_movie.ratings.to_a
1536
+
1537
+ expect_no_queries do
1538
+ fresh_movie.ratings.any?.should be expected_result
1539
+ end
1540
+ end
1541
+ end
1542
+ end
1543
+
1544
+ let(:movie) do
1545
+ Movie.create!
1546
+ end
1547
+
1548
+ context "when nothing exists on the association" do
1549
+
1550
+ context "when no document is added" do
1551
+
1552
+ let!(:movie) do
1553
+ Movie.create!
1554
+ end
1555
+
1556
+ it "returns false" do
1557
+ expect(movie.ratings.any?).to be false
1558
+ end
1559
+
1560
+ let(:expected_result) { false }
1561
+ include_examples 'does not query database when association is loaded'
1562
+ end
1563
+
1564
+ context "when the document is destroyed" do
1565
+
1566
+ before do
1567
+ Rating.create!
1568
+ end
1569
+
1570
+ let!(:movie) do
1571
+ Movie.create!
1572
+ end
1573
+
1574
+ it "returns false" do
1575
+ movie.destroy
1576
+ expect(movie.ratings.any?).to be false
1577
+ end
1578
+ end
1579
+ end
1580
+
1581
+ context "when appending to a association and _loaded/_unloaded are empty" do
1582
+
1583
+ let!(:movie) do
1584
+ Movie.create!
1585
+ end
1586
+
1587
+ before do
1588
+ movie.ratings << Rating.new
1589
+ end
1590
+
1591
+ it "returns true" do
1592
+ expect(movie.ratings.any?).to be true
1593
+ end
1594
+
1595
+ context 'when association is not loaded' do
1596
+ before do
1597
+ movie.ratings._loaded?.should be false
1598
+ end
1599
+
1600
+ it 'does not query the database because it knows about the added models' do
1601
+ expect_no_queries do
1602
+ movie.ratings.any?.should be true
1603
+ end
1604
+ end
1605
+ end
1606
+
1607
+ context 'when association is loaded' do
1608
+ it 'does not query database' do
1609
+ expect_no_queries do
1610
+ movie.ratings.any?.should be true
1611
+ end
1612
+
1613
+ movie.ratings.to_a
1614
+
1615
+ expect_no_queries do
1616
+ movie.ratings.any?.should be true
1617
+ end
1618
+ end
1619
+ end
1620
+ end
1621
+
1622
+ context "when appending to a association in a transaction" do
1623
+ require_transaction_support
1624
+
1625
+ let!(:movie) do
1626
+ Movie.create!
1627
+ end
1628
+
1629
+ it "returns true" do
1630
+ movie.with_session do |session|
1631
+ session.with_transaction do
1632
+ expect{ movie.ratings << Rating.new }.to_not raise_error
1633
+ expect(movie.ratings.any?).to be true
1634
+ end
1635
+ end
1636
+ end
1637
+ end
1638
+
1639
+ context "when documents have been persisted" do
1640
+
1641
+ let!(:rating) do
1642
+ movie.ratings.create!(value: 1)
1643
+ end
1644
+
1645
+ it "returns true" do
1646
+ expect(movie.ratings.any?).to be true
1647
+ end
1648
+
1649
+ let(:expected_result) { true }
1650
+ include_examples 'does not query database when association is loaded'
1651
+ end
1652
+
1653
+ context "when documents have not been persisted" do
1654
+
1655
+ let!(:rating) do
1656
+ movie.ratings.build(value: 1)
1657
+ end
1658
+
1659
+ it "returns false" do
1660
+ expect(movie.ratings.any?).to be true
1661
+ end
1662
+ end
1663
+
1664
+ context "when new documents exist in the database" do
1665
+ before do
1666
+ Rating.create!(ratable: movie)
1667
+ end
1668
+
1669
+ it "returns true" do
1670
+ expect(movie.ratings.any?).to be true
1671
+ end
1672
+ end
1673
+ end
1674
+
1675
+ describe "#create" do
1676
+
1677
+ context "when providing multiple attributes" do
1678
+
1679
+ let(:person) do
1680
+ Person.create!
1681
+ end
1682
+
1683
+ let!(:posts) do
1684
+ person.posts.create!([{ text: "Test1" }, { text: "Test2" }])
1685
+ end
1686
+
1687
+ it "creates multiple documents" do
1688
+ expect(posts.size).to eq(2)
1689
+ end
1690
+
1691
+ it "sets the first attributes" do
1692
+ expect(posts.first.text).to eq("Test1")
1693
+ end
1694
+
1695
+ it "sets the second attributes" do
1696
+ expect(posts.last.text).to eq("Test2")
1697
+ end
1698
+
1699
+ it "persists the children" do
1700
+ expect(person.posts.count).to eq(2)
1701
+ end
1702
+ end
1703
+
1704
+ context "when the association is not polymorphic" do
1705
+
1706
+ context "when the parent is a new record" do
1707
+
1708
+ let(:person) do
1709
+ Person.new
1710
+ end
1711
+
1712
+ let(:post) do
1713
+ person.posts.create!(text: "Testing")
1714
+ end
1715
+
1716
+ it "raises an unsaved document error" do
1717
+ expect { post }.to raise_error(Mongoid::Errors::UnsavedDocument)
1718
+ end
1719
+ end
1720
+
1721
+ context "when.creating the document" do
1722
+
1723
+ context "when the operation is successful" do
1724
+
1725
+ let(:person) do
1726
+ Person.create!
1727
+ end
1728
+
1729
+ let!(:post) do
1730
+ person.posts.create!(text: "Testing")
1731
+ end
1732
+
1733
+ it "creates the document" do
1734
+ expect(person.posts).to eq([ post ])
1735
+ end
1736
+ end
1737
+
1738
+ context "when the operation fails" do
1739
+
1740
+ let(:person) do
1741
+ Person.create!
1742
+ end
1743
+
1744
+ let!(:existing) do
1745
+ Post.create!
1746
+ end
1747
+
1748
+ it "raises an error" do
1749
+ expect {
1750
+ person.posts.create! do |doc|
1751
+ doc._id = existing.id
1752
+ end
1753
+ }.to raise_error(Mongo::Error::OperationFailure)
1754
+ end
1755
+ end
1756
+ end
1757
+
1758
+ context "when the parent is not a new record" do
1759
+
1760
+ let(:person) do
1761
+ Person.create!
1762
+ end
1763
+
1764
+ let!(:post) do
1765
+ person.posts.create!(text: "Testing") do |post|
1766
+ post.content = "The Content"
1767
+ end
1768
+ end
1769
+
1770
+ it "sets the foreign key on the association" do
1771
+ expect(post.person_id).to eq(person.id)
1772
+ end
1773
+
1774
+ it "sets the base on the inverse association" do
1775
+ expect(post.person).to eq(person)
1776
+ end
1777
+
1778
+ it "sets the attributes" do
1779
+ expect(post.text).to eq("Testing")
1780
+ end
1781
+
1782
+ it "saves the target" do
1783
+ expect(post).to_not be_a_new_record
1784
+ end
1785
+
1786
+ it "calls the passed block" do
1787
+ expect(post.content).to eq("The Content")
1788
+ end
1789
+
1790
+ it "adds the document to the target" do
1791
+ expect(person.posts.count).to eq(1)
1792
+ end
1793
+ end
1794
+
1795
+ context "when passing a new object" do
1796
+
1797
+ let!(:odd) do
1798
+ Odd.create!(name: 'one')
1799
+ end
1800
+
1801
+ let!(:even) do
1802
+ odd.evens.create!(name: 'two', odds: [Odd.new(name: 'three')])
1803
+ end
1804
+
1805
+ it "only push one even to the list" do
1806
+ expect(odd.evens.count).to eq(1)
1807
+ end
1808
+
1809
+ it "saves the reference back" do
1810
+ expect(odd.evens.first.odds.count).to eq(1)
1811
+ end
1812
+
1813
+ it "only saves one even" do
1814
+ expect(Even.count).to eq(1)
1815
+ end
1816
+
1817
+ it "saves the first odd and the second" do
1818
+ expect(Odd.count).to eq(2)
1819
+ end
1820
+ end
1821
+ end
1822
+
1823
+ context "when the association is polymorphic" do
1824
+
1825
+ context "when the parent is a new record" do
1826
+
1827
+ let(:movie) do
1828
+ Movie.new
1829
+ end
1830
+
1831
+ let(:rating) do
1832
+ movie.ratings.create!(value: 1)
1833
+ end
1834
+
1835
+ it "raises an unsaved document error" do
1836
+ expect { rating }.to raise_error(Mongoid::Errors::UnsavedDocument)
1837
+ end
1838
+ end
1839
+
1840
+ context "when the parent is not a new record" do
1841
+
1842
+ let(:movie) do
1843
+ Movie.create!
1844
+ end
1845
+
1846
+ let!(:rating) do
1847
+ movie.ratings.create!(value: 3)
1848
+ end
1849
+
1850
+ it "sets the foreign key on the association" do
1851
+ expect(rating.ratable_id).to eq(movie.id)
1852
+ end
1853
+
1854
+ it "sets the base on the inverse association" do
1855
+ expect(rating.ratable).to eq(movie)
1856
+ end
1857
+
1858
+ it "sets the attributes" do
1859
+ expect(rating.value).to eq(3)
1860
+ end
1861
+
1862
+ it "saves the target" do
1863
+ expect(rating).to_not be_new_record
1864
+ end
1865
+
1866
+ it "adds the document to the target" do
1867
+ expect(movie.ratings.count).to eq(1)
1868
+ end
1869
+ end
1870
+ end
1871
+
1872
+ context "when using a different primary_key" do
1873
+
1874
+ let(:person) do
1875
+ Person.create!(username: 'arthurnn')
1876
+ end
1877
+
1878
+ let(:drug) do
1879
+ person.drugs.create!
1880
+ end
1881
+
1882
+ it 'saves pk value on fk field' do
1883
+ expect(drug.person_id).to eq('arthurnn')
1884
+ end
1885
+ end
1886
+ end
1887
+
1888
+ describe "#create!" do
1889
+
1890
+ context "when providing multiple attributes" do
1891
+
1892
+ let(:person) do
1893
+ Person.create!
1894
+ end
1895
+
1896
+ let!(:posts) do
1897
+ person.posts.create!([{ text: "Test1" }, { text: "Test2" }])
1898
+ end
1899
+
1900
+ it "creates multiple documents" do
1901
+ expect(posts.size).to eq(2)
1902
+ end
1903
+
1904
+ it "sets the first attributes" do
1905
+ expect(posts.first.text).to eq("Test1")
1906
+ end
1907
+
1908
+ it "sets the second attributes" do
1909
+ expect(posts.last.text).to eq("Test2")
1910
+ end
1911
+
1912
+ it "persists the children" do
1913
+ expect(person.posts.count).to eq(2)
1914
+ end
1915
+ end
1916
+
1917
+ context "when the association is not polymorphic" do
1918
+
1919
+ context "when the parent is a new record" do
1920
+
1921
+ let(:person) do
1922
+ Person.new
1923
+ end
1924
+
1925
+ let(:post) do
1926
+ person.posts.create!(title: "Testing")
1927
+ end
1928
+
1929
+ it "raises an unsaved document error" do
1930
+ expect { post }.to raise_error(Mongoid::Errors::UnsavedDocument)
1931
+ end
1932
+ end
1933
+
1934
+ context "when the parent is not a new record" do
1935
+
1936
+ let(:person) do
1937
+ Person.create!
1938
+ end
1939
+
1940
+ let!(:post) do
1941
+ person.posts.create!(title: "Testing")
1942
+ end
1943
+
1944
+ it "sets the foreign key on the association" do
1945
+ expect(post.person_id).to eq(person.id)
1946
+ end
1947
+
1948
+ it "sets the base on the inverse association" do
1949
+ expect(post.person).to eq(person)
1950
+ end
1951
+
1952
+ it "sets the attributes" do
1953
+ expect(post.title).to eq("Testing")
1954
+ end
1955
+
1956
+ it "saves the target" do
1957
+ expect(post).to_not be_a_new_record
1958
+ end
1959
+
1960
+ it "adds the document to the target" do
1961
+ expect(person.posts.count).to eq(1)
1962
+ end
1963
+
1964
+ context "when validation fails" do
1965
+
1966
+ it "raises an error" do
1967
+ expect {
1968
+ person.posts.create!(title: "$$$")
1969
+ }.to raise_error(Mongoid::Errors::Validations)
1970
+ end
1971
+ end
1972
+ end
1973
+ end
1974
+
1975
+ context "when the association is polymorphic" do
1976
+
1977
+ context "when the parent is a new record" do
1978
+
1979
+ let(:movie) do
1980
+ Movie.new
1981
+ end
1982
+
1983
+ let(:rating) do
1984
+ movie.ratings.create!(value: 1)
1985
+ end
1986
+
1987
+ it "raises an unsaved document error" do
1988
+ expect { rating }.to raise_error(Mongoid::Errors::UnsavedDocument)
1989
+ end
1990
+ end
1991
+
1992
+ context "when the parent is not a new record" do
1993
+
1994
+ let(:movie) do
1995
+ Movie.create!
1996
+ end
1997
+
1998
+ let!(:rating) do
1999
+ movie.ratings.create!(value: 4)
2000
+ end
2001
+
2002
+ it "sets the foreign key on the association" do
2003
+ expect(rating.ratable_id).to eq(movie.id)
2004
+ end
2005
+
2006
+ it "sets the base on the inverse association" do
2007
+ expect(rating.ratable).to eq(movie)
2008
+ end
2009
+
2010
+ it "sets the attributes" do
2011
+ expect(rating.value).to eq(4)
2012
+ end
2013
+
2014
+ it "saves the target" do
2015
+ expect(rating).to_not be_new_record
2016
+ end
2017
+
2018
+ it "adds the document to the target" do
2019
+ expect(movie.ratings.count).to eq(1)
2020
+ end
2021
+
2022
+ context "when validation fails" do
2023
+
2024
+ it "raises an error" do
2025
+ expect {
2026
+ movie.ratings.create!(value: 1000)
2027
+ }.to raise_error(Mongoid::Errors::Validations)
2028
+ end
2029
+ end
2030
+ end
2031
+ end
2032
+ end
2033
+
2034
+ describe "#criteria" do
2035
+
2036
+ let(:base) do
2037
+ Movie.new
2038
+ end
2039
+
2040
+ context "when the association is polymorphic" do
2041
+
2042
+ let(:association) do
2043
+ Movie.relations["ratings"]
2044
+ end
2045
+
2046
+ let(:criteria) do
2047
+ association.criteria(base)
2048
+ end
2049
+
2050
+ it "includes the type in the criteria" do
2051
+ expect(criteria.selector).to eq(
2052
+ {
2053
+ "ratable_id" => base.id,
2054
+ "ratable_type" => "Movie"
2055
+ }
2056
+ )
2057
+ end
2058
+ end
2059
+
2060
+ context "when the association is not polymorphic" do
2061
+
2062
+ let(:association) do
2063
+ Person.relations["posts"]
2064
+ end
2065
+
2066
+ let(:base) do
2067
+ Person.new
2068
+ end
2069
+
2070
+ let(:criteria) do
2071
+ association.criteria(base)
2072
+ end
2073
+
2074
+ it "does not include the type in the criteria" do
2075
+ expect(criteria.selector).to eq({ "person_id" => base.id })
2076
+ end
2077
+ end
2078
+ end
2079
+
2080
+ describe "#delete" do
2081
+
2082
+ let!(:person) do
2083
+ Person.create!(username: 'arthurnn')
2084
+ end
2085
+
2086
+ context "when the document is found" do
2087
+
2088
+ context "when no dependent option is set" do
2089
+
2090
+ context "when we are assigning attributes" do
2091
+
2092
+ let!(:drug) do
2093
+ person.drugs.create!
2094
+ end
2095
+
2096
+ before do
2097
+ Mongoid::Threaded.begin_execution(:assign)
2098
+ end
2099
+
2100
+ after do
2101
+ Mongoid::Threaded.exit_execution(:assign)
2102
+ end
2103
+
2104
+ let(:deleted) do
2105
+ person.drugs.delete(drug)
2106
+ end
2107
+
2108
+ it "does not cascade" do
2109
+ expect(deleted.changes.keys).to eq([ "person_id" ])
2110
+ end
2111
+ end
2112
+
2113
+ context "when the document is loaded" do
2114
+
2115
+ let!(:drug) do
2116
+ person.drugs.create!
2117
+ end
2118
+
2119
+ let!(:deleted) do
2120
+ person.drugs.delete(drug)
2121
+ end
2122
+
2123
+ it "returns the document" do
2124
+ expect(deleted).to eq(drug)
2125
+ end
2126
+
2127
+ it "deletes the foreign key" do
2128
+ expect(drug.person_id).to be_nil
2129
+ end
2130
+
2131
+ it "removes the document from the association" do
2132
+ expect(person.drugs).to_not include(drug)
2133
+ end
2134
+ end
2135
+
2136
+ context "when the document is not loaded" do
2137
+
2138
+ let!(:drug) do
2139
+ Drug.create!(person_id: person.username)
2140
+ end
2141
+
2142
+ let!(:deleted) do
2143
+ person.drugs.delete(drug)
2144
+ end
2145
+
2146
+ it "returns the document" do
2147
+ expect(deleted).to eq(drug)
2148
+ end
2149
+
2150
+ it "deletes the foreign key" do
2151
+ expect(drug.person_id).to be_nil
2152
+ end
2153
+
2154
+ it "removes the document from the association" do
2155
+ expect(person.drugs).to_not include(drug)
2156
+ end
2157
+ end
2158
+ end
2159
+
2160
+ context "when dependent is delete" do
2161
+
2162
+ context "when the document is loaded" do
2163
+
2164
+ let!(:post) do
2165
+ person.posts.create!(title: "test")
2166
+ end
2167
+
2168
+ let!(:deleted) do
2169
+ person.posts.delete(post)
2170
+ end
2171
+
2172
+ it "returns the document" do
2173
+ expect(deleted).to eq(post)
2174
+ end
2175
+
2176
+ it "deletes the document" do
2177
+ expect(post).to be_destroyed
2178
+ end
2179
+
2180
+ it "removes the document from the association" do
2181
+ expect(person.posts).to_not include(post)
2182
+ end
2183
+ end
2184
+
2185
+ context "when the document is not loaded" do
2186
+
2187
+ let!(:post) do
2188
+ Post.create!(title: "foo", person_id: person.id)
2189
+ end
2190
+
2191
+ let!(:deleted) do
2192
+ person.posts.delete(post)
2193
+ end
2194
+
2195
+ it "returns the document" do
2196
+ expect(deleted).to eq(post)
2197
+ end
2198
+
2199
+ it "deletes the document" do
2200
+ expect(post).to be_destroyed
2201
+ end
2202
+
2203
+ it "removes the document from the association" do
2204
+ expect(person.posts).to_not include(post)
2205
+ end
2206
+ end
2207
+ end
2208
+ end
2209
+
2210
+ context "when the document is not found" do
2211
+
2212
+ let!(:post) do
2213
+ Post.create!(title: "foo")
2214
+ end
2215
+
2216
+ let!(:deleted) do
2217
+ person.posts.delete(post)
2218
+ end
2219
+
2220
+ it "returns nil" do
2221
+ expect(deleted).to be_nil
2222
+ end
2223
+
2224
+ it "does not delete the document" do
2225
+ expect(post).to be_persisted
2226
+ end
2227
+ end
2228
+ end
2229
+
2230
+ [ :delete_all, :destroy_all ].each do |method|
2231
+
2232
+ describe "##{method}" do
2233
+
2234
+ context "when the association is not polymorphic" do
2235
+
2236
+ context "when conditions are provided" do
2237
+
2238
+ let(:person) do
2239
+ Person.create!(username: 'durran')
2240
+ end
2241
+
2242
+ let!(:post1) { person.posts.create!(title: "Testing") }
2243
+ let!(:post2) { person.posts.create!(title: "Test") }
2244
+
2245
+ it "removes the correct posts" do
2246
+ person.posts.send(method, { title: "Testing" })
2247
+ expect(person.posts.count).to eq(1)
2248
+ expect(person.reload.posts_count).to eq(1) if method == :destroy_all
2249
+ end
2250
+
2251
+ it "deletes the documents from the database" do
2252
+ person.posts.send(method, { title: "Testing" })
2253
+ expect(Post.where(title: "Testing").count).to eq(0)
2254
+ end
2255
+
2256
+ it "returns the number of documents deleted" do
2257
+ expect(person.posts.send(method, { title: "Testing" })).to eq(1)
2258
+ end
2259
+
2260
+ it "sets the association locally" do
2261
+ person.posts.send(method, { title: "Testing" })
2262
+ expect(person.posts).to eq([post2])
2263
+ end
2264
+ end
2265
+
2266
+ context "when conditions are not provided" do
2267
+
2268
+ let(:person) do
2269
+ Person.create!
2270
+ end
2271
+
2272
+ before do
2273
+ person.posts.create!(title: "Testing")
2274
+ person.posts.create!(title: "Test")
2275
+ end
2276
+
2277
+ it "removes the correct posts" do
2278
+ person.posts.send(method)
2279
+ expect(person.posts.count).to eq(0)
2280
+ end
2281
+
2282
+ it "deletes the documents from the database" do
2283
+ person.posts.send(method)
2284
+ expect(Post.where(title: "Testing").count).to eq(0)
2285
+ end
2286
+
2287
+ it "returns the number of documents deleted" do
2288
+ expect(person.posts.send(method)).to eq(2)
2289
+ end
2290
+
2291
+ it "sets the association locally" do
2292
+ person.posts.send(method)
2293
+ expect(person.posts).to eq([])
2294
+ end
2295
+ end
2296
+ end
2297
+
2298
+ context "when the association is polymorphic" do
2299
+
2300
+ context "when conditions are provided" do
2301
+
2302
+ let(:movie) do
2303
+ Movie.create!(title: "Bladerunner")
2304
+ end
2305
+
2306
+ let!(:rating1) { movie.ratings.create!(value: 1) }
2307
+ let!(:rating2) { movie.ratings.create!(value: 2) }
2308
+
2309
+ it "removes the correct ratings" do
2310
+ movie.ratings.send(method, { value: 1 })
2311
+ expect(movie.ratings.count).to eq(1)
2312
+ end
2313
+
2314
+ it "deletes the documents from the database" do
2315
+ movie.ratings.send(method, { value: 1 })
2316
+ expect(Rating.where(value: 1).count).to eq(0)
2317
+ end
2318
+
2319
+ it "returns the number of documents deleted" do
2320
+ expect(movie.ratings.send(method, { value: 1 })).to eq(1)
2321
+ end
2322
+
2323
+ it "sets the association locally" do
2324
+ movie.ratings.send(method, { value: 1 })
2325
+ expect(movie.ratings).to eq([rating2])
2326
+ end
2327
+ end
2328
+
2329
+ context "when conditions are not provided" do
2330
+
2331
+ let(:movie) do
2332
+ Movie.create!(title: "Bladerunner")
2333
+ end
2334
+
2335
+ before do
2336
+ movie.ratings.create!(value: 1)
2337
+ movie.ratings.create!(value: 2)
2338
+ end
2339
+
2340
+ it "removes the correct ratings" do
2341
+ movie.ratings.send(method)
2342
+ expect(movie.ratings.count).to eq(0)
2343
+ end
2344
+
2345
+ it "deletes the documents from the database" do
2346
+ movie.ratings.send(method)
2347
+ expect(Rating.where(value: 1).count).to eq(0)
2348
+ end
2349
+
2350
+ it "returns the number of documents deleted" do
2351
+ expect(movie.ratings.send(method)).to eq(2)
2352
+ end
2353
+
2354
+ it "sets the association locally" do
2355
+ movie.ratings.send(method)
2356
+ expect(movie.ratings).to eq([])
2357
+ end
2358
+ end
2359
+ end
2360
+ end
2361
+ end
2362
+
2363
+ describe ".embedded?" do
2364
+
2365
+ it "returns false" do
2366
+ expect(described_class).to_not be_embedded
2367
+ end
2368
+ end
2369
+
2370
+ describe "#exists?" do
2371
+
2372
+ let!(:person) do
2373
+ Person.create!
2374
+ end
2375
+
2376
+ context "when documents exist in the database" do
2377
+
2378
+ before do
2379
+ person.posts.create!
2380
+ end
2381
+
2382
+ it "returns true" do
2383
+ expect(person.posts.exists?).to be true
2384
+ end
2385
+
2386
+ context 'when association is not loaded' do
2387
+ it 'queries database on each call' do
2388
+ expect_query(1) do
2389
+ person.posts.exists?.should be true
2390
+ end
2391
+
2392
+ expect_query(1) do
2393
+ person.posts.exists?.should be true
2394
+ end
2395
+ end
2396
+ end
2397
+
2398
+ context 'when association is loaded' do
2399
+ it 'queries database on each call' do
2400
+ expect_query(1) do
2401
+ person.posts.exists?.should be true
2402
+ end
2403
+
2404
+ person.posts.to_a
2405
+
2406
+ expect_query(1) do
2407
+ person.posts.exists?.should be true
2408
+ end
2409
+ end
2410
+ end
2411
+ end
2412
+
2413
+ context "when documents exist in application but not in database" do
2414
+
2415
+ before do
2416
+ person.posts.build
2417
+ end
2418
+
2419
+ it "returns false" do
2420
+ expect(person.posts.exists?).to be false
2421
+ end
2422
+
2423
+ context 'when association is not loaded' do
2424
+ it 'queries database on each call' do
2425
+ expect_query(1) do
2426
+ person.posts.exists?.should be false
2427
+ end
2428
+
2429
+ expect_query(1) do
2430
+ person.posts.exists?.should be false
2431
+ end
2432
+ end
2433
+ end
2434
+
2435
+ context 'when association is loaded' do
2436
+ it 'queries database on each call' do
2437
+ expect_query(1) do
2438
+ person.posts.exists?.should be false
2439
+ end
2440
+
2441
+ person.posts.to_a
2442
+
2443
+ expect_query(1) do
2444
+ person.posts.exists?.should be false
2445
+ end
2446
+ end
2447
+ end
2448
+ end
2449
+
2450
+ context "when no documents exist" do
2451
+
2452
+ it "returns false" do
2453
+ expect(person.posts.exists?).to be false
2454
+ end
2455
+
2456
+ context 'when association is not loaded' do
2457
+ it 'queries database on each call' do
2458
+ expect_query(1) do
2459
+ person.posts.exists?.should be false
2460
+ end
2461
+
2462
+ expect_query(1) do
2463
+ person.posts.exists?.should be false
2464
+ end
2465
+ end
2466
+ end
2467
+
2468
+ context 'when association is loaded' do
2469
+ it 'queries database on each call' do
2470
+ expect_query(1) do
2471
+ person.posts.exists?.should be false
2472
+ end
2473
+
2474
+ person.posts.to_a
2475
+
2476
+ expect_query(1) do
2477
+ person.posts.exists?.should be false
2478
+ end
2479
+ end
2480
+ end
2481
+ end
2482
+ end
2483
+
2484
+ describe "#find" do
2485
+
2486
+ context "when iterating after the find" do
2487
+
2488
+ let(:person) do
2489
+ Person.create!
2490
+ end
2491
+
2492
+ let(:post_id) do
2493
+ person.posts.first.id
2494
+ end
2495
+
2496
+ before do
2497
+ 5.times { person.posts.create! }
2498
+ end
2499
+
2500
+ it "does not change the in memory size" do
2501
+ expect {
2502
+ person.posts.find(post_id)
2503
+ }.not_to change { person.posts.to_a.size }
2504
+ end
2505
+ end
2506
+
2507
+ context "when the association is not polymorphic" do
2508
+
2509
+ let(:person) do
2510
+ Person.create!
2511
+ end
2512
+
2513
+ let!(:post_one) do
2514
+ person.posts.create!(title: "Test")
2515
+ end
2516
+
2517
+ let!(:post_two) do
2518
+ person.posts.create!(title: "OMG I has associations")
2519
+ end
2520
+
2521
+ context "when providing an id" do
2522
+
2523
+ context "when the id matches" do
2524
+
2525
+ let(:post) do
2526
+ person.posts.find(post_one.id)
2527
+ end
2528
+
2529
+ it "returns the matching document" do
2530
+ expect(post).to eq(post_one)
2531
+ end
2532
+ end
2533
+
2534
+ context "when the id matches but is not scoped to the association" do
2535
+
2536
+ let(:post) do
2537
+ Post.create!(title: "Unscoped")
2538
+ end
2539
+
2540
+ it "raises an error" do
2541
+ expect {
2542
+ person.posts.find(post.id)
2543
+ }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Post with id\(s\)/)
2544
+ end
2545
+ end
2546
+
2547
+ context "when the id does not match" do
2548
+
2549
+ context "when config set to raise error" do
2550
+
2551
+ before do
2552
+ Mongoid.raise_not_found_error = true
2553
+ end
2554
+
2555
+ it "raises an error" do
2556
+ expect {
2557
+ person.posts.find(BSON::ObjectId.new)
2558
+ }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Post with id\(s\)/)
2559
+ end
2560
+ end
2561
+
2562
+ context "when config set not to raise error" do
2563
+
2564
+ let(:post) do
2565
+ person.posts.find(BSON::ObjectId.new)
2566
+ end
2567
+
2568
+ before do
2569
+ Mongoid.raise_not_found_error = false
2570
+ end
2571
+
2572
+ after do
2573
+ Mongoid.raise_not_found_error = true
2574
+ end
2575
+
2576
+ it "returns nil" do
2577
+ expect(post).to be_nil
2578
+ end
2579
+ end
2580
+ end
2581
+ end
2582
+
2583
+ context "when providing an array of ids" do
2584
+
2585
+ context "when the ids match" do
2586
+
2587
+ let(:posts) do
2588
+ person.posts.find([ post_one.id, post_two.id ])
2589
+ end
2590
+
2591
+ it "returns the matching documents" do
2592
+ expect(posts).to eq([ post_one, post_two ])
2593
+ end
2594
+ end
2595
+
2596
+ context "when the ids do not match" do
2597
+
2598
+ context "when config set to raise error" do
2599
+
2600
+ before do
2601
+ Mongoid.raise_not_found_error = true
2602
+ end
2603
+
2604
+ it "raises an error" do
2605
+ expect {
2606
+ person.posts.find([ BSON::ObjectId.new ])
2607
+ }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Post with id\(s\)/)
2608
+ end
2609
+ end
2610
+
2611
+ context "when config set not to raise error" do
2612
+
2613
+ let(:posts) do
2614
+ person.posts.find([ BSON::ObjectId.new ])
2615
+ end
2616
+
2617
+ before do
2618
+ Mongoid.raise_not_found_error = false
2619
+ end
2620
+
2621
+ after do
2622
+ Mongoid.raise_not_found_error = true
2623
+ end
2624
+
2625
+ it "returns an empty array" do
2626
+ expect(posts).to be_empty
2627
+ end
2628
+ end
2629
+ end
2630
+ end
2631
+ end
2632
+
2633
+ context "when the association is polymorphic" do
2634
+
2635
+ let(:movie) do
2636
+ Movie.create!
2637
+ end
2638
+
2639
+ let!(:rating_one) do
2640
+ movie.ratings.create!(value: 1)
2641
+ end
2642
+
2643
+ let!(:rating_two) do
2644
+ movie.ratings.create!(value: 5)
2645
+ end
2646
+
2647
+ context "when providing an id" do
2648
+
2649
+ context "when the id matches" do
2650
+
2651
+ let(:rating) do
2652
+ movie.ratings.find(rating_one.id)
2653
+ end
2654
+
2655
+ it "returns the matching document" do
2656
+ expect(rating).to eq(rating_one)
2657
+ end
2658
+ end
2659
+
2660
+ context "when the id does not match" do
2661
+
2662
+ context "when config set to raise error" do
2663
+
2664
+ before do
2665
+ Mongoid.raise_not_found_error = true
2666
+ end
2667
+
2668
+ it "raises an error" do
2669
+ expect {
2670
+ movie.ratings.find(BSON::ObjectId.new)
2671
+ }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Rating with id\(s\)/)
2672
+ end
2673
+ end
2674
+
2675
+ context "when config set not to raise error" do
2676
+
2677
+ let(:rating) do
2678
+ movie.ratings.find(BSON::ObjectId.new)
2679
+ end
2680
+
2681
+ before do
2682
+ Mongoid.raise_not_found_error = false
2683
+ end
2684
+
2685
+ after do
2686
+ Mongoid.raise_not_found_error = true
2687
+ end
2688
+
2689
+ it "returns nil" do
2690
+ expect(rating).to be_nil
2691
+ end
2692
+ end
2693
+ end
2694
+ end
2695
+
2696
+ context "when providing an array of ids" do
2697
+
2698
+ context "when the ids match" do
2699
+
2700
+ let(:ratings) do
2701
+ movie.ratings.find([ rating_one.id, rating_two.id ])
2702
+ end
2703
+
2704
+ it "returns the first matching document" do
2705
+ expect(ratings).to include(rating_one)
2706
+ end
2707
+
2708
+ it "returns the second matching document" do
2709
+ expect(ratings).to include(rating_two)
2710
+ end
2711
+
2712
+ it "returns the correct number of documents" do
2713
+ expect(ratings.size).to eq(2)
2714
+ end
2715
+ end
2716
+
2717
+ context "when the ids do not match" do
2718
+
2719
+ context "when config set to raise error" do
2720
+
2721
+ before do
2722
+ Mongoid.raise_not_found_error = true
2723
+ end
2724
+
2725
+ it "raises an error" do
2726
+ expect {
2727
+ movie.ratings.find([ BSON::ObjectId.new ])
2728
+ }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Rating with id\(s\)/)
2729
+ end
2730
+ end
2731
+
2732
+ context "when config set not to raise error" do
2733
+
2734
+ let(:ratings) do
2735
+ movie.ratings.find([ BSON::ObjectId.new ])
2736
+ end
2737
+
2738
+ before do
2739
+ Mongoid.raise_not_found_error = false
2740
+ end
2741
+
2742
+ after do
2743
+ Mongoid.raise_not_found_error = true
2744
+ end
2745
+
2746
+ it "returns an empty array" do
2747
+ expect(ratings).to be_empty
2748
+ end
2749
+ end
2750
+ end
2751
+ end
2752
+ end
2753
+
2754
+ context "with block" do
2755
+ let!(:author) do
2756
+ Person.create!(title: 'Person')
2757
+ end
2758
+
2759
+ let!(:post_one) do
2760
+ author.posts.create!(title: 'post one')
2761
+ end
2762
+
2763
+ let!(:post_two) do
2764
+ author.posts.create!(title: 'post two')
2765
+ end
2766
+
2767
+ it "finds one" do
2768
+ expect(
2769
+ author.posts.find do |post|
2770
+ post.title == 'post one'
2771
+ end
2772
+ ).to be_a(Post)
2773
+ end
2774
+
2775
+ it "returns first match of multiple" do
2776
+ expect(
2777
+ author.posts.find do |post|
2778
+ ['post one', 'post two'].include?(post.title)
2779
+ end
2780
+ ).to eq(post_one)
2781
+ end
2782
+
2783
+ it "returns nil when not found" do
2784
+ expect(
2785
+ author.posts.find do |post|
2786
+ post.title == 'non exiting one'
2787
+ end
2788
+ ).to be_nil
2789
+ end
2790
+ end
2791
+ end
2792
+
2793
+ describe "#find_or_create_by" do
2794
+
2795
+ context "when the association is not polymorphic" do
2796
+
2797
+ let(:person) do
2798
+ Person.create!
2799
+ end
2800
+
2801
+ let!(:post) do
2802
+ person.posts.create!(title: "Testing")
2803
+ end
2804
+
2805
+ context "when the document exists" do
2806
+
2807
+ let(:found) do
2808
+ person.posts.find_or_create_by(title: "Testing")
2809
+ end
2810
+
2811
+ it "returns the document" do
2812
+ expect(found).to eq(post)
2813
+ end
2814
+
2815
+ it "keeps the document in the association" do
2816
+ expect(found.person).to eq(person)
2817
+ end
2818
+ end
2819
+
2820
+ context "when the document does not exist" do
2821
+
2822
+ context "when there is no criteria attached" do
2823
+
2824
+ let(:found) do
2825
+ person.posts.find_or_create_by(title: "Test") do |post|
2826
+ post.content = "The Content"
2827
+ end
2828
+ end
2829
+
2830
+ it "sets the new document attributes" do
2831
+ expect(found.title).to eq("Test")
2832
+ end
2833
+
2834
+ it "returns a newly persisted document" do
2835
+ expect(found).to be_persisted
2836
+ end
2837
+
2838
+ it "calls the passed block" do
2839
+ expect(found.content).to eq("The Content")
2840
+ end
2841
+
2842
+ it "keeps the document in the association" do
2843
+ expect(found.person).to eq(person)
2844
+ end
2845
+ end
2846
+
2847
+ context "when a criteria is attached" do
2848
+
2849
+ let(:found) do
2850
+ person.posts.recent.find_or_create_by(title: "Test")
2851
+ end
2852
+
2853
+ it "sets the new document attributes" do
2854
+ expect(found.title).to eq("Test")
2855
+ end
2856
+
2857
+ it "returns a newly persisted document" do
2858
+ expect(found).to be_persisted
2859
+ end
2860
+
2861
+ it "keeps the document in the association" do
2862
+ expect(found.person).to eq(person)
2863
+ end
2864
+ end
2865
+ end
2866
+ end
2867
+
2868
+ context "when the association is polymorphic" do
2869
+
2870
+ let(:movie) do
2871
+ Movie.create!
2872
+ end
2873
+
2874
+ let!(:rating) do
2875
+ movie.ratings.create!(value: 1)
2876
+ end
2877
+
2878
+ context "when the document exists" do
2879
+
2880
+ let(:found) do
2881
+ movie.ratings.find_or_create_by(value: 1)
2882
+ end
2883
+
2884
+ it "returns the document" do
2885
+ expect(found).to eq(rating)
2886
+ end
2887
+
2888
+ it "keeps the document in the association" do
2889
+ expect(found.ratable).to eq(movie)
2890
+ end
2891
+ end
2892
+
2893
+ context "when the document does not exist" do
2894
+
2895
+ let(:found) do
2896
+ movie.ratings.find_or_create_by(value: 3)
2897
+ end
2898
+
2899
+ it "sets the new document attributes" do
2900
+ expect(found.value).to eq(3)
2901
+ end
2902
+
2903
+ it "returns a newly persisted document" do
2904
+ expect(found).to be_persisted
2905
+ end
2906
+
2907
+ it "keeps the document in the association" do
2908
+ expect(found.ratable).to eq(movie)
2909
+ end
2910
+ end
2911
+ end
2912
+ end
2913
+
2914
+ describe "#find_or_create_by!" do
2915
+
2916
+ context "when the association is not polymorphic" do
2917
+
2918
+ let(:person) do
2919
+ Person.create!
2920
+ end
2921
+
2922
+ let!(:post) do
2923
+ person.posts.create!(title: "Testing")
2924
+ end
2925
+
2926
+ context "when the document exists" do
2927
+
2928
+ let(:found) do
2929
+ person.posts.find_or_create_by!(title: "Testing")
2930
+ end
2931
+
2932
+ it "returns the document" do
2933
+ expect(found).to eq(post)
2934
+ end
2935
+
2936
+ it "keeps the document in the association" do
2937
+ expect(found.person).to eq(person)
2938
+ end
2939
+ end
2940
+
2941
+ context "when the document does not exist" do
2942
+
2943
+ context "when there is no criteria attached" do
2944
+
2945
+ let(:found) do
2946
+ person.posts.find_or_create_by!(title: "Test") do |post|
2947
+ post.content = "The Content"
2948
+ end
2949
+ end
2950
+
2951
+ it "sets the new document attributes" do
2952
+ expect(found.title).to eq("Test")
2953
+ end
2954
+
2955
+ it "returns a newly persisted document" do
2956
+ expect(found).to be_persisted
2957
+ end
2958
+
2959
+ it "calls the passed block" do
2960
+ expect(found.content).to eq("The Content")
2961
+ end
2962
+
2963
+ it "keeps the document in the association" do
2964
+ expect(found.person).to eq(person)
2965
+ end
2966
+ end
2967
+
2968
+ context "when a criteria is attached" do
2969
+
2970
+ let(:found) do
2971
+ person.posts.recent.find_or_create_by!(title: "Test")
2972
+ end
2973
+
2974
+ it "sets the new document attributes" do
2975
+ expect(found.title).to eq("Test")
2976
+ end
2977
+
2978
+ it "returns a newly persisted document" do
2979
+ expect(found).to be_persisted
2980
+ end
2981
+
2982
+ it "keeps the document in the association" do
2983
+ expect(found.person).to eq(person)
2984
+ end
2985
+ end
2986
+ end
2987
+ end
2988
+
2989
+ context "when the association is polymorphic" do
2990
+
2991
+ let(:movie) do
2992
+ Movie.create!
2993
+ end
2994
+
2995
+ let!(:rating) do
2996
+ movie.ratings.create!(value: 1)
2997
+ end
2998
+
2999
+ context "when the document exists" do
3000
+
3001
+ let(:found) do
3002
+ movie.ratings.find_or_create_by!(value: 1)
3003
+ end
3004
+
3005
+ it "returns the document" do
3006
+ expect(found).to eq(rating)
3007
+ end
3008
+
3009
+ it "keeps the document in the association" do
3010
+ expect(found.ratable).to eq(movie)
3011
+ end
3012
+ end
3013
+
3014
+ context "when the document does not exist" do
3015
+
3016
+ let(:found) do
3017
+ movie.ratings.find_or_create_by!(value: 3)
3018
+ end
3019
+
3020
+ it "sets the new document attributes" do
3021
+ expect(found.value).to eq(3)
3022
+ end
3023
+
3024
+ it "returns a newly persisted document" do
3025
+ expect(found).to be_persisted
3026
+ end
3027
+
3028
+ it "keeps the document in the association" do
3029
+ expect(found.ratable).to eq(movie)
3030
+ end
3031
+
3032
+ context "when validation fails" do
3033
+
3034
+ it "raises an error" do
3035
+ expect {
3036
+ movie.comments.find_or_create_by!(title: "")
3037
+ }.to raise_error(Mongoid::Errors::Validations)
3038
+ end
3039
+ end
3040
+ end
3041
+ end
3042
+ end
3043
+
3044
+ describe "#find_or_initialize_by" do
3045
+
3046
+ context "when the association is not polymorphic" do
3047
+
3048
+ let(:person) do
3049
+ Person.create!
3050
+ end
3051
+
3052
+ let!(:post) do
3053
+ person.posts.create!(title: "Testing")
3054
+ end
3055
+
3056
+ context "when the document exists" do
3057
+
3058
+ let(:found) do
3059
+ person.posts.find_or_initialize_by(title: "Testing")
3060
+ end
3061
+
3062
+ it "returns the document" do
3063
+ expect(found).to eq(post)
3064
+ end
3065
+ end
3066
+
3067
+ context "when the document does not exist" do
3068
+
3069
+ let(:found) do
3070
+ person.posts.find_or_initialize_by(title: "Test") do |post|
3071
+ post.content = "The Content"
3072
+ end
3073
+ end
3074
+
3075
+ it "sets the new document attributes" do
3076
+ expect(found.title).to eq("Test")
3077
+ end
3078
+
3079
+ it "returns a non persisted document" do
3080
+ expect(found).to_not be_persisted
3081
+ end
3082
+
3083
+ it "calls the passed block" do
3084
+ expect(found.content).to eq("The Content")
3085
+ end
3086
+ end
3087
+ end
3088
+
3089
+ context "when the association is polymorphic" do
3090
+
3091
+ let(:movie) do
3092
+ Movie.create!
3093
+ end
3094
+
3095
+ let!(:rating) do
3096
+ movie.ratings.create!(value: 1)
3097
+ end
3098
+
3099
+ context "when the document exists" do
3100
+
3101
+ let(:found) do
3102
+ movie.ratings.find_or_initialize_by(value: 1)
3103
+ end
3104
+
3105
+ it "returns the document" do
3106
+ expect(found).to eq(rating)
3107
+ end
3108
+ end
3109
+
3110
+ context "when the document does not exist" do
3111
+
3112
+ let(:found) do
3113
+ movie.ratings.find_or_initialize_by(value: 3)
3114
+ end
3115
+
3116
+ it "sets the new document attributes" do
3117
+ expect(found.value).to eq(3)
3118
+ end
3119
+
3120
+ it "returns a non persisted document" do
3121
+ expect(found).to_not be_persisted
3122
+ end
3123
+ end
3124
+ end
3125
+ end
3126
+
3127
+ describe "#initialize" do
3128
+
3129
+ context "when an illegal mixed association exists" do
3130
+
3131
+ let(:post) do
3132
+ Post.new
3133
+ end
3134
+
3135
+ it "raises an error" do
3136
+ expect {
3137
+ post.videos
3138
+ }.to raise_error(Mongoid::Errors::MixedRelations)
3139
+ end
3140
+ end
3141
+
3142
+ context "when a cyclic association exists" do
3143
+
3144
+ let(:post) do
3145
+ Post.new
3146
+ end
3147
+
3148
+ it "does not raise an error" do
3149
+ expect(post.roles).to be_empty
3150
+ end
3151
+ end
3152
+ end
3153
+
3154
+ describe "#last" do
3155
+
3156
+ let(:person) do
3157
+ Person.create!
3158
+ end
3159
+
3160
+ let!(:persisted_post) do
3161
+ person.posts.create!
3162
+ end
3163
+
3164
+ context "when a new document is added" do
3165
+
3166
+ let!(:new_post) do
3167
+ person.posts.new
3168
+ end
3169
+
3170
+ context "when the target is subsequently loaded" do
3171
+
3172
+ before do
3173
+ person.posts.entries
3174
+ end
3175
+
3176
+ it "returns the expected last document" do
3177
+ expect(person.posts.last).to eq(new_post)
3178
+ end
3179
+ end
3180
+ end
3181
+ end
3182
+
3183
+ describe "#max" do
3184
+
3185
+ let(:person) do
3186
+ Person.create!
3187
+ end
3188
+
3189
+ let(:post_one) do
3190
+ Post.create!(rating: 5)
3191
+ end
3192
+
3193
+ let(:post_two) do
3194
+ Post.create!(rating: 10)
3195
+ end
3196
+
3197
+ before do
3198
+ person.posts.push(post_one, post_two)
3199
+ end
3200
+
3201
+ let(:max) do
3202
+ person.posts.max do |a,b|
3203
+ a.rating <=> b.rating
3204
+ end
3205
+ end
3206
+
3207
+ it "returns the document with the max value of the supplied field" do
3208
+ expect(max).to eq(post_two)
3209
+ end
3210
+ end
3211
+
3212
+ describe "#max_by" do
3213
+
3214
+ let(:person) do
3215
+ Person.create!
3216
+ end
3217
+
3218
+ let(:post_one) do
3219
+ Post.create!(rating: 5)
3220
+ end
3221
+
3222
+ let(:post_two) do
3223
+ Post.create!(rating: 10)
3224
+ end
3225
+
3226
+ before do
3227
+ person.posts.push(post_one, post_two)
3228
+ end
3229
+
3230
+ let(:max) do
3231
+ person.posts.max_by(&:rating)
3232
+ end
3233
+
3234
+ it "returns the document with the max value of the supplied field" do
3235
+ expect(max).to eq(post_two)
3236
+ end
3237
+ end
3238
+
3239
+ describe "#method_missing" do
3240
+
3241
+ let!(:person) do
3242
+ Person.create!
3243
+ end
3244
+
3245
+ let!(:post_one) do
3246
+ person.posts.create!(title: "First", content: "Posting")
3247
+ end
3248
+
3249
+ let!(:post_two) do
3250
+ person.posts.create!(title: "Second", content: "Testing")
3251
+ end
3252
+
3253
+ context "when providing a single criteria" do
3254
+
3255
+ let(:posts) do
3256
+ person.posts.where(title: "First")
3257
+ end
3258
+
3259
+ it "applies the criteria to the documents" do
3260
+ expect(posts).to eq([ post_one ])
3261
+ end
3262
+
3263
+ context 'when providing a collation' do
3264
+ min_server_version '3.4'
3265
+
3266
+ let(:posts) do
3267
+ person.posts.where(title: "FIRST").collation(locale: 'en_US', strength: 2)
3268
+ end
3269
+
3270
+ it "applies the collation option to the query" do
3271
+ expect(posts).to eq([ post_one ])
3272
+ end
3273
+ end
3274
+ end
3275
+
3276
+ context "when providing a criteria class method" do
3277
+
3278
+ let(:posts) do
3279
+ person.posts.posting
3280
+ end
3281
+
3282
+ it "applies the criteria to the documents" do
3283
+ expect(posts).to eq([ post_one ])
3284
+ end
3285
+ end
3286
+
3287
+ context "when chaining criteria" do
3288
+
3289
+ let(:posts) do
3290
+ person.posts.posting.where(:title.in => [ "First" ])
3291
+ end
3292
+
3293
+ it "applies the criteria to the documents" do
3294
+ expect(posts).to eq([ post_one ])
3295
+ end
3296
+ end
3297
+
3298
+ context "when delegating methods" do
3299
+
3300
+ describe "#distinct" do
3301
+
3302
+ let(:values) do
3303
+ person.posts.distinct(:title)
3304
+ end
3305
+
3306
+ it "returns the distinct values for the fields" do
3307
+ expect(values).to include("First")
3308
+ expect(values).to include("Second")
3309
+ end
3310
+ end
3311
+ end
3312
+ end
3313
+
3314
+ describe "#min" do
3315
+
3316
+ let(:person) do
3317
+ Person.create!
3318
+ end
3319
+
3320
+ let(:post_one) do
3321
+ Post.create!(rating: 5)
3322
+ end
3323
+
3324
+ let(:post_two) do
3325
+ Post.create!(rating: 10)
3326
+ end
3327
+
3328
+ before do
3329
+ person.posts.push(post_one, post_two)
3330
+ end
3331
+
3332
+ let(:min) do
3333
+ person.posts.min do |a, b|
3334
+ a.rating <=> b.rating
3335
+ end
3336
+ end
3337
+
3338
+ it "returns the min value of the supplied field" do
3339
+ expect(min).to eq(post_one)
3340
+ end
3341
+ end
3342
+
3343
+ describe "#min_by" do
3344
+
3345
+ let(:person) do
3346
+ Person.create!
3347
+ end
3348
+
3349
+ let(:post_one) do
3350
+ Post.create!(rating: 5)
3351
+ end
3352
+
3353
+ let(:post_two) do
3354
+ Post.create!(rating: 10)
3355
+ end
3356
+
3357
+ before do
3358
+ person.posts.push(post_one, post_two)
3359
+ end
3360
+
3361
+ let(:min) do
3362
+ person.posts.min_by(&:rating)
3363
+ end
3364
+
3365
+ it "returns the min value of the supplied field" do
3366
+ expect(min).to eq(post_one)
3367
+ end
3368
+ end
3369
+
3370
+ describe "#nullify_all" do
3371
+
3372
+ context "when the inverse has not been loaded" do
3373
+
3374
+ let(:person) do
3375
+ Person.create!
3376
+ end
3377
+
3378
+ let!(:post_one) do
3379
+ person.posts.create!(title: "One")
3380
+ end
3381
+
3382
+ let!(:post_two) do
3383
+ person.posts.create!(title: "Two")
3384
+ end
3385
+
3386
+ let(:from_db) do
3387
+ Person.first
3388
+ end
3389
+
3390
+ before do
3391
+ from_db.posts.nullify_all
3392
+ end
3393
+
3394
+ it "loads the targets before nullifying" do
3395
+ expect(from_db.posts).to be_empty
3396
+ end
3397
+
3398
+ it "persists the base nullifications" do
3399
+ expect(Person.first.posts).to be_empty
3400
+ end
3401
+
3402
+ it "persists the inverse nullifications" do
3403
+ Post.all.each do |post|
3404
+ expect(post.person).to be_nil
3405
+ end
3406
+ end
3407
+ end
3408
+
3409
+ context "when the association is not polymorphic" do
3410
+
3411
+ let(:person) do
3412
+ Person.create!
3413
+ end
3414
+
3415
+ let!(:post_one) do
3416
+ person.posts.create!(title: "One")
3417
+ end
3418
+
3419
+ let!(:post_two) do
3420
+ person.posts.create!(title: "Two")
3421
+ end
3422
+
3423
+ before do
3424
+ person.posts.nullify_all
3425
+ end
3426
+
3427
+ it "removes all the foreign keys from the target" do
3428
+ [ post_one, post_two ].each do |post|
3429
+ expect(post.person_id).to be_nil
3430
+ end
3431
+ end
3432
+
3433
+ it "removes all the references from the target" do
3434
+ [ post_one, post_two ].each do |post|
3435
+ expect(post.person).to be_nil
3436
+ end
3437
+ end
3438
+
3439
+ it "saves the documents" do
3440
+ expect(post_one.reload.person).to be_nil
3441
+ end
3442
+
3443
+ context "when adding a nullified document back to the association" do
3444
+
3445
+ before do
3446
+ person.posts.push(post_one)
3447
+ end
3448
+
3449
+ it "persists the association" do
3450
+ expect(person.posts(true)).to eq([ post_one ])
3451
+ end
3452
+ end
3453
+ end
3454
+
3455
+ context "when the association is polymorphic" do
3456
+
3457
+ let(:movie) do
3458
+ Movie.create!(title: "Oldboy")
3459
+ end
3460
+
3461
+ let!(:rating_one) do
3462
+ movie.ratings.create!(value: 10)
3463
+ end
3464
+
3465
+ let!(:rating_two) do
3466
+ movie.ratings.create!(value: 9)
3467
+ end
3468
+
3469
+ before do
3470
+ movie.ratings.nullify_all
3471
+ end
3472
+
3473
+ it "removes all the foreign keys from the target" do
3474
+ [ rating_one, rating_two ].each do |rating|
3475
+ expect(rating.ratable_id).to be_nil
3476
+ end
3477
+ end
3478
+
3479
+ it "removes all the references from the target" do
3480
+ [ rating_one, rating_two ].each do |rating|
3481
+ expect(rating.ratable).to be_nil
3482
+ end
3483
+ end
3484
+ end
3485
+ end
3486
+
3487
+ describe "#respond_to?" do
3488
+
3489
+ let(:person) do
3490
+ Person.new
3491
+ end
3492
+
3493
+ let(:posts) do
3494
+ person.posts
3495
+ end
3496
+
3497
+ Array.public_instance_methods.each do |method|
3498
+
3499
+ context "when checking #{method}" do
3500
+
3501
+ it "returns true" do
3502
+ expect(posts.respond_to?(method)).to be true
3503
+ end
3504
+ end
3505
+ end
3506
+
3507
+ Mongoid::Association::Referenced::HasMany::Proxy.public_instance_methods.each do |method|
3508
+
3509
+ context "when checking #{method}" do
3510
+
3511
+ it "returns true" do
3512
+ expect(posts.respond_to?(method)).to be true
3513
+ end
3514
+ end
3515
+ end
3516
+
3517
+ Post.scopes.keys.each do |method|
3518
+
3519
+ context "when checking #{method}" do
3520
+
3521
+ it "returns true" do
3522
+ expect(posts.respond_to?(method)).to be true
3523
+ end
3524
+ end
3525
+ end
3526
+ end
3527
+
3528
+ describe "#scoped" do
3529
+
3530
+ let(:person) do
3531
+ Person.new
3532
+ end
3533
+
3534
+ let(:scoped) do
3535
+ person.posts.scoped
3536
+ end
3537
+
3538
+ it "returns the association criteria" do
3539
+ expect(scoped).to be_a(Mongoid::Criteria)
3540
+ end
3541
+
3542
+ it "returns with an empty selector" do
3543
+ expect(scoped.selector).to eq({ "person_id" => person.id })
3544
+ end
3545
+ end
3546
+
3547
+ [ :size, :length ].each do |method|
3548
+
3549
+ describe "##{method}" do
3550
+
3551
+ let(:movie) do
3552
+ Movie.create!
3553
+ end
3554
+
3555
+ context "when documents have been persisted" do
3556
+
3557
+ let!(:rating) do
3558
+ movie.ratings.create!(value: 1)
3559
+ end
3560
+
3561
+ it "returns 1" do
3562
+ expect(movie.ratings.send(method)).to eq(1)
3563
+ end
3564
+ end
3565
+
3566
+ context "when documents have not been persisted" do
3567
+
3568
+ before do
3569
+ movie.ratings.build(value: 1)
3570
+ movie.ratings.create!(value: 2)
3571
+ end
3572
+
3573
+ it "returns the total number of documents" do
3574
+ expect(movie.ratings.send(method)).to eq(2)
3575
+ end
3576
+ end
3577
+ end
3578
+ end
3579
+
3580
+ describe "#unscoped" do
3581
+
3582
+ context "when the association has no default scope" do
3583
+
3584
+ let!(:person) do
3585
+ Person.create!
3586
+ end
3587
+
3588
+ let!(:post_one) do
3589
+ person.posts.create!(title: "first")
3590
+ end
3591
+
3592
+ let!(:post_two) do
3593
+ Post.create!(title: "second")
3594
+ end
3595
+
3596
+ let(:unscoped) do
3597
+ person.posts.unscoped
3598
+ end
3599
+
3600
+ it "returns only the associated documents" do
3601
+ expect(unscoped).to eq([ post_one ])
3602
+ end
3603
+ end
3604
+
3605
+ context "when the association has a default scope" do
3606
+
3607
+ let!(:church) do
3608
+ Church.create!
3609
+ end
3610
+
3611
+ let!(:acolyte_one) do
3612
+ church.acolytes.create!(name: "first")
3613
+ end
3614
+
3615
+ let!(:acolyte_two) do
3616
+ Acolyte.create!(name: "second")
3617
+ end
3618
+
3619
+ let(:unscoped) do
3620
+ church.acolytes.unscoped
3621
+ end
3622
+
3623
+ it "only returns associated documents" do
3624
+ expect(unscoped).to eq([ acolyte_one ])
3625
+ end
3626
+
3627
+ it "removes the default scoping options" do
3628
+ expect(unscoped.options).to eq({})
3629
+ end
3630
+ end
3631
+ end
3632
+
3633
+ context "when the association has an order defined" do
3634
+
3635
+ let(:person) do
3636
+ Person.create!
3637
+ end
3638
+
3639
+ let(:post_one) do
3640
+ OrderedPost.create!(rating: 10, title: '1')
3641
+ end
3642
+
3643
+ let(:post_two) do
3644
+ OrderedPost.create!(rating: 20, title: '2')
3645
+ end
3646
+
3647
+ let(:post_three) do
3648
+ OrderedPost.create!(rating: 20, title: '3')
3649
+ end
3650
+
3651
+ before do
3652
+ person.ordered_posts.nullify_all
3653
+ person.ordered_posts.push(post_one, post_two, post_three)
3654
+ end
3655
+
3656
+ it "order documents" do
3657
+ expect(person.ordered_posts(true)).to eq(
3658
+ [post_two, post_three, post_one]
3659
+ )
3660
+ end
3661
+
3662
+ it "chaining order criteria" do
3663
+ expect(person.ordered_posts.order_by(:title.desc).to_a).to eq(
3664
+ [post_three, post_two, post_one]
3665
+ )
3666
+ end
3667
+ end
3668
+
3669
+ context "when reloading the association" do
3670
+
3671
+ let!(:person) do
3672
+ Person.create!
3673
+ end
3674
+
3675
+ let!(:post_one) do
3676
+ Post.create!(title: "one")
3677
+ end
3678
+
3679
+ let!(:post_two) do
3680
+ Post.create!(title: "two")
3681
+ end
3682
+
3683
+ before do
3684
+ person.posts << post_one
3685
+ end
3686
+
3687
+ context "when the association references the same documents" do
3688
+
3689
+ before do
3690
+ Post.collection.find({ _id: post_one.id }).
3691
+ update_one({ "$set" => { title: "reloaded" }})
3692
+ end
3693
+
3694
+ let(:reloaded) do
3695
+ person.posts(true)
3696
+ end
3697
+
3698
+ it "reloads the document from the database" do
3699
+ expect(reloaded.first.title).to eq("reloaded")
3700
+ end
3701
+ end
3702
+
3703
+ context "when the association references different documents" do
3704
+
3705
+ before do
3706
+ person.posts << post_two
3707
+ end
3708
+
3709
+ let(:reloaded) do
3710
+ person.posts(true)
3711
+ end
3712
+
3713
+ it "reloads the first document from the database" do
3714
+ expect(reloaded).to include(post_one)
3715
+ end
3716
+
3717
+ it "reloads the new document from the database" do
3718
+ expect(reloaded).to include(post_two)
3719
+ end
3720
+ end
3721
+ end
3722
+
3723
+ context "when the parent is using integer ids" do
3724
+
3725
+ let(:jar) do
3726
+ Jar.create! do |doc|
3727
+ doc._id = 1
3728
+ end
3729
+ end
3730
+
3731
+ it "allows creation of the document" do
3732
+ expect(jar.id).to eq(1)
3733
+ end
3734
+ end
3735
+
3736
+ context "when adding a document" do
3737
+
3738
+ let(:person) do
3739
+ Person.new
3740
+ end
3741
+
3742
+ let(:post_one) do
3743
+ Post.new
3744
+ end
3745
+
3746
+ let(:first_add) do
3747
+ person.posts.push(post_one)
3748
+ end
3749
+
3750
+ context "when chaining a second add" do
3751
+
3752
+ let(:post_two) do
3753
+ Post.new
3754
+ end
3755
+
3756
+ let(:result) do
3757
+ first_add.push(post_two)
3758
+ end
3759
+
3760
+ it "adds both documents" do
3761
+ expect(result).to eq([ post_one, post_two ])
3762
+ end
3763
+ end
3764
+ end
3765
+
3766
+ context "when pushing with a before_add callback" do
3767
+
3768
+ let(:artist) do
3769
+ Artist.new
3770
+ end
3771
+
3772
+ let(:album) do
3773
+ Album.new
3774
+ end
3775
+
3776
+ context "when execution raises no errors" do
3777
+
3778
+ before do
3779
+ artist.albums << album
3780
+ end
3781
+
3782
+ it "it executes method callbacks" do
3783
+ expect(artist.before_add_referenced_called).to be true
3784
+ end
3785
+
3786
+ it "it executes proc callbacks" do
3787
+ expect(album.before_add_called).to be true
3788
+ end
3789
+
3790
+ it "adds the document to the association" do
3791
+ expect(artist.albums).to eq([ album ])
3792
+ end
3793
+ end
3794
+
3795
+ context "when execution raises errors" do
3796
+
3797
+ before do
3798
+ expect(artist).to receive(:before_add_album).and_raise
3799
+ begin; artist.albums << album; rescue; end
3800
+ end
3801
+
3802
+ it "does not add the document to the association" do
3803
+ expect(artist.albums).to be_empty
3804
+ end
3805
+ end
3806
+ end
3807
+
3808
+ context "when pushing with an after_add callback" do
3809
+
3810
+ let(:artist) do
3811
+ Artist.new
3812
+ end
3813
+
3814
+ let(:album) do
3815
+ Album.new
3816
+ end
3817
+
3818
+ it "executes the callback" do
3819
+ artist.albums << album
3820
+ expect(artist.after_add_referenced_called).to be true
3821
+ end
3822
+
3823
+ context "when execution raises errors" do
3824
+
3825
+ before do
3826
+ expect(artist).to receive(:after_add_album).and_raise
3827
+ begin; artist.albums << album; rescue; end
3828
+ end
3829
+
3830
+ it "adds the document to the association" do
3831
+ expect(artist.albums).to eq([ album ])
3832
+ end
3833
+ end
3834
+
3835
+ context 'when the association already exists' do
3836
+
3837
+ before do
3838
+ artist.albums << album
3839
+ album.save!
3840
+ artist.save!
3841
+ expect(artist).not_to receive(:after_add_album)
3842
+ end
3843
+
3844
+ let(:reloaded_album) do
3845
+ Album.where(artist_id: artist.id).first
3846
+ end
3847
+
3848
+ it 'does not execute the callback when the association is accessed' do
3849
+ expect(reloaded_album.artist.after_add_referenced_called).to be(nil)
3850
+ end
3851
+ end
3852
+ end
3853
+
3854
+ context "when #delete or #clear with before_remove callback" do
3855
+
3856
+ let(:artist) do
3857
+ Artist.new
3858
+ end
3859
+
3860
+ let(:album) do
3861
+ Album.new
3862
+ end
3863
+
3864
+ before do
3865
+ artist.albums << album
3866
+ end
3867
+
3868
+ context "when executing raises no errors" do
3869
+
3870
+ describe "#delete" do
3871
+
3872
+ before do
3873
+ artist.albums.delete album
3874
+ end
3875
+
3876
+ it "executes the callback" do
3877
+ expect(artist.before_remove_referenced_called).to be true
3878
+ end
3879
+
3880
+ it "removes the document from the association" do
3881
+ expect(artist.albums).to be_empty
3882
+ end
3883
+ end
3884
+
3885
+ describe "#clear" do
3886
+
3887
+ before do
3888
+ artist.albums.clear
3889
+ end
3890
+
3891
+ it "executes the callback" do
3892
+ expect(artist.before_remove_referenced_called).to be true
3893
+ end
3894
+
3895
+ it "clears the association" do
3896
+ expect(artist.albums).to be_empty
3897
+ end
3898
+ end
3899
+
3900
+ context "when execution raises errors" do
3901
+
3902
+ before do
3903
+ expect(artist).to receive(:before_remove_album).and_raise
3904
+ end
3905
+
3906
+ describe "#delete" do
3907
+
3908
+ before do
3909
+ begin; artist.albums.delete(album); rescue; end
3910
+ end
3911
+
3912
+ it "does not remove the document from the association" do
3913
+ expect(artist.albums).to eq([ album ])
3914
+ end
3915
+ end
3916
+
3917
+ describe "#clear" do
3918
+
3919
+ before do
3920
+ begin; artist.albums.clear; rescue; end
3921
+ end
3922
+
3923
+ it "does not clear the association" do
3924
+ expect(artist.albums).to eq([ album ])
3925
+ end
3926
+ end
3927
+ end
3928
+ end
3929
+ end
3930
+
3931
+ context "when #delete or #clear with after_remove callback" do
3932
+
3933
+ let(:artist) do
3934
+ Artist.new
3935
+ end
3936
+
3937
+ let(:album) do
3938
+ Album.new
3939
+ end
3940
+
3941
+ before do
3942
+ artist.albums << album
3943
+ end
3944
+
3945
+ context "without errors" do
3946
+
3947
+ describe "#delete" do
3948
+
3949
+ before do
3950
+ artist.albums.delete album
3951
+ end
3952
+
3953
+ it "executes the callback" do
3954
+ expect(artist.after_remove_referenced_called).to be true
3955
+ end
3956
+ end
3957
+
3958
+ describe "#clear" do
3959
+
3960
+ before do
3961
+ artist.albums.clear
3962
+ end
3963
+
3964
+ it "executes the callback" do
3965
+ artist.albums.clear
3966
+ expect(artist.after_remove_referenced_called).to be true
3967
+ end
3968
+ end
3969
+ end
3970
+
3971
+ context "when errors are raised" do
3972
+
3973
+ before do
3974
+ expect(artist).to receive(:after_remove_album).and_raise
3975
+ end
3976
+
3977
+ describe "#delete" do
3978
+
3979
+ before do
3980
+ begin; artist.albums.delete(album); rescue; end
3981
+ end
3982
+
3983
+ it "removes the documents from the association" do
3984
+ expect(artist.albums).to be_empty
3985
+ end
3986
+ end
3987
+
3988
+ describe "#clear" do
3989
+
3990
+ before do
3991
+ begin; artist.albums.clear; rescue; end
3992
+ end
3993
+
3994
+ it "removes the documents from the association" do
3995
+ expect(artist.albums).to be_empty
3996
+ end
3997
+ end
3998
+ end
3999
+ end
4000
+
4001
+ context "when executing a criteria call on an ordered association" do
4002
+
4003
+ let(:person) do
4004
+ Person.create!
4005
+ end
4006
+
4007
+ let!(:post_one) do
4008
+ person.ordered_posts.create!(rating: 1)
4009
+ end
4010
+
4011
+ let!(:post_two) do
4012
+ person.ordered_posts.create!(rating: 5)
4013
+ end
4014
+
4015
+ let(:criteria) do
4016
+ person.ordered_posts.only(:_id, :rating)
4017
+ end
4018
+
4019
+ it "does not drop the ordering" do
4020
+ expect(criteria).to eq([ post_two, post_one ])
4021
+ end
4022
+ end
4023
+
4024
+ context "when accessing a scope named open" do
4025
+
4026
+ let(:person) do
4027
+ Person.create!
4028
+ end
4029
+
4030
+ let!(:post) do
4031
+ person.posts.create!(title: "open")
4032
+ end
4033
+
4034
+ it "returns the appropriate documents" do
4035
+ expect(person.posts.open).to eq([ post ])
4036
+ end
4037
+ end
4038
+
4039
+ context "when accessing a association named parent" do
4040
+
4041
+ let!(:parent) do
4042
+ Odd.create!(name: "odd parent")
4043
+ end
4044
+
4045
+ let(:child) do
4046
+ Even.create!(parent_id: parent.id, name: "original even child")
4047
+ end
4048
+
4049
+ it "updates the child after accessing the parent" do
4050
+ # Access parent association on the child to make sure it is loaded
4051
+ child.parent
4052
+
4053
+ new_child_name = "updated even child"
4054
+
4055
+ child.name = new_child_name
4056
+ child.save!
4057
+
4058
+ reloaded = Even.find(child.id)
4059
+ expect(reloaded.name).to eq(new_child_name)
4060
+ end
4061
+ end
4062
+
4063
+ context 'when a document has referenced and embedded associations' do
4064
+
4065
+ let(:agent) do
4066
+ Agent.new
4067
+ end
4068
+
4069
+ let(:basic) do
4070
+ Basic.new
4071
+ end
4072
+
4073
+ let(:address) do
4074
+ Address.new
4075
+ end
4076
+
4077
+ before do
4078
+ agent.basics << basic
4079
+ agent.address = address
4080
+ end
4081
+
4082
+ it 'saves the document correctly' do
4083
+ expect(agent.save!).to be(true)
4084
+ end
4085
+ end
4086
+
4087
+ context 'when the two models use the same name to refer to the association' do
4088
+
4089
+ let(:agent) do
4090
+ Agent.new
4091
+ end
4092
+
4093
+ let(:band) do
4094
+ Band.new
4095
+ end
4096
+
4097
+ before do
4098
+ agent.same_name = band
4099
+ agent.save!
4100
+ band.save!
4101
+ band.reload
4102
+ end
4103
+
4104
+ it 'constructs the correct criteria' do
4105
+ expect(band.same_name).to eq([agent])
4106
+ end
4107
+ end
4108
+
4109
+ context "when removing a document with counter_cache on" do
4110
+ let(:post) { Post.create! }
4111
+ let(:person1) { Person.create! }
4112
+ let(:person2) { Person.create! }
4113
+
4114
+ before do
4115
+ post.update_attribute(:person, person1)
4116
+ expect(person1.posts_count).to eq 1
4117
+
4118
+ person2
4119
+ post.update_attribute(:person, person2)
4120
+ person1.reload
4121
+ expect(person1.posts_count).to eq 0
4122
+ expect(person2.posts_count).to eq 1
4123
+
4124
+ post.update_attribute(:person, nil)
4125
+ person1.reload
4126
+ person2.reload
4127
+ end
4128
+
4129
+ it "the count field is updated" do
4130
+ expect(person2.posts_count).to eq 0
4131
+ end
4132
+ end
4133
+
4134
+ context "when there is a foreign key in the aliased associations" do
4135
+ it "has the correct aliases" do
4136
+ expect(Band.aliased_associations["artist_ids"]).to eq("artists")
4137
+ expect(Artist.aliased_associations.key?("band_id")).to be false
4138
+ expect(Artist.aliased_fields["band"]).to eq("band_id")
4139
+ end
4140
+ end
4141
+
4142
+ context "when executing concat on foreign key array from the db" do
4143
+ config_override :legacy_attributes, false
4144
+
4145
+ before do
4146
+ Agent.create!
4147
+ Basic.create!
4148
+ end
4149
+
4150
+ let!(:agent) { Agent.first }
4151
+ let!(:basic) { Basic.first }
4152
+
4153
+ before do
4154
+ agent.basic_ids.concat([basic.id])
4155
+ end
4156
+
4157
+ it "works on the first attempt" do
4158
+ expect(agent.basic_ids).to eq([basic.id])
4159
+ end
4160
+ end
4161
+ end