mongoid 3.1.6 → 4.0.0

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 (562) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +432 -8
  3. data/README.md +5 -6
  4. data/lib/config/locales/en.yml +32 -18
  5. data/lib/mongoid/atomic/paths/embedded/many.rb +1 -1
  6. data/lib/mongoid/atomic/paths/embedded/one.rb +1 -1
  7. data/lib/mongoid/atomic/paths/embedded.rb +0 -30
  8. data/lib/mongoid/atomic/paths/root.rb +0 -13
  9. data/lib/mongoid/atomic.rb +1 -12
  10. data/lib/mongoid/attributes/dynamic.rb +154 -0
  11. data/lib/mongoid/attributes/nested.rb +82 -0
  12. data/lib/mongoid/attributes/processing.rb +13 -66
  13. data/lib/mongoid/attributes.rb +63 -101
  14. data/lib/mongoid/{dirty.rb → changeable.rb} +32 -2
  15. data/lib/mongoid/composable.rb +105 -0
  16. data/lib/mongoid/config/options.rb +1 -1
  17. data/lib/mongoid/config.rb +3 -9
  18. data/lib/mongoid/contextual/aggregable/mongo.rb +7 -9
  19. data/lib/mongoid/contextual/atomic.rb +53 -53
  20. data/lib/mongoid/contextual/geo_near.rb +1 -1
  21. data/lib/mongoid/contextual/map_reduce.rb +4 -2
  22. data/lib/mongoid/contextual/memory.rb +18 -6
  23. data/lib/mongoid/contextual/mongo.rb +64 -56
  24. data/lib/mongoid/contextual/none.rb +90 -0
  25. data/lib/mongoid/contextual/text_search.rb +178 -0
  26. data/lib/mongoid/contextual.rb +2 -0
  27. data/lib/mongoid/copyable.rb +2 -3
  28. data/lib/mongoid/{criterion → criteria}/findable.rb +7 -47
  29. data/lib/mongoid/{criterion/inspection.rb → criteria/inspectable.rb} +2 -2
  30. data/lib/mongoid/{criterion → criteria}/marshalable.rb +3 -1
  31. data/lib/mongoid/{criterion → criteria}/modifiable.rb +28 -8
  32. data/lib/mongoid/criteria/permission.rb +70 -0
  33. data/lib/mongoid/{criterion/scoping.rb → criteria/scopable.rb} +2 -2
  34. data/lib/mongoid/criteria.rb +39 -34
  35. data/lib/mongoid/document.rb +32 -17
  36. data/lib/mongoid/errors/document_not_destroyed.rb +25 -0
  37. data/lib/mongoid/errors/document_not_found.rb +2 -1
  38. data/lib/mongoid/errors/invalid_storage_options.rb +1 -1
  39. data/lib/mongoid/errors/invalid_storage_parent.rb +26 -0
  40. data/lib/mongoid/errors/invalid_value.rb +16 -0
  41. data/lib/mongoid/errors/mongoid_error.rb +1 -1
  42. data/lib/mongoid/errors/readonly_document.rb +24 -0
  43. data/lib/mongoid/errors.rb +4 -1
  44. data/lib/mongoid/extensions/array.rb +3 -3
  45. data/lib/mongoid/extensions/big_decimal.rb +1 -1
  46. data/lib/mongoid/extensions/boolean.rb +15 -17
  47. data/lib/mongoid/extensions/date.rb +1 -1
  48. data/lib/mongoid/extensions/date_time.rb +3 -3
  49. data/lib/mongoid/extensions/float.rb +2 -1
  50. data/lib/mongoid/extensions/hash.rb +3 -3
  51. data/lib/mongoid/extensions/integer.rb +1 -1
  52. data/lib/mongoid/extensions/object.rb +7 -7
  53. data/lib/mongoid/extensions/object_id.rb +5 -5
  54. data/lib/mongoid/extensions/range.rb +9 -3
  55. data/lib/mongoid/extensions/regexp.rb +1 -1
  56. data/lib/mongoid/extensions/set.rb +1 -1
  57. data/lib/mongoid/extensions/string.rb +6 -18
  58. data/lib/mongoid/extensions/symbol.rb +1 -1
  59. data/lib/mongoid/extensions/time.rb +3 -3
  60. data/lib/mongoid/extensions/time_with_zone.rb +1 -1
  61. data/lib/mongoid/extensions.rb +2 -7
  62. data/lib/mongoid/factory.rb +8 -6
  63. data/lib/mongoid/fields/foreign_key.rb +3 -3
  64. data/lib/mongoid/fields/localized.rb +1 -1
  65. data/lib/mongoid/fields/standard.rb +5 -17
  66. data/lib/mongoid/fields/validators/macro.rb +15 -5
  67. data/lib/mongoid/fields.rb +41 -8
  68. data/lib/mongoid/{finders.rb → findable.rb} +8 -2
  69. data/lib/mongoid/indexable/specification.rb +104 -0
  70. data/lib/mongoid/{indexes → indexable}/validators/options.rb +2 -1
  71. data/lib/mongoid/{indexes.rb → indexable.rb} +50 -55
  72. data/lib/mongoid/{inspection.rb → inspectable.rb} +15 -11
  73. data/lib/mongoid/{callbacks.rb → interceptable.rb} +30 -62
  74. data/lib/mongoid/log_subscriber.rb +55 -0
  75. data/lib/mongoid/{matchers → matchable}/all.rb +1 -1
  76. data/lib/mongoid/{matchers → matchable}/and.rb +2 -2
  77. data/lib/mongoid/{matchers → matchable}/default.rb +1 -1
  78. data/lib/mongoid/{matchers → matchable}/exists.rb +1 -1
  79. data/lib/mongoid/{matchers → matchable}/gt.rb +1 -1
  80. data/lib/mongoid/{matchers → matchable}/gte.rb +1 -1
  81. data/lib/mongoid/{matchers → matchable}/in.rb +2 -2
  82. data/lib/mongoid/{matchers → matchable}/lt.rb +1 -1
  83. data/lib/mongoid/{matchers → matchable}/lte.rb +1 -1
  84. data/lib/mongoid/{matchers → matchable}/ne.rb +2 -2
  85. data/lib/mongoid/{matchers → matchable}/nin.rb +3 -2
  86. data/lib/mongoid/{matchers → matchable}/or.rb +2 -2
  87. data/lib/mongoid/{matchers → matchable}/size.rb +1 -1
  88. data/lib/mongoid/matchable.rb +152 -0
  89. data/lib/mongoid/persistable/creatable.rb +188 -0
  90. data/lib/mongoid/persistable/deletable.rb +149 -0
  91. data/lib/mongoid/persistable/destroyable.rb +60 -0
  92. data/lib/mongoid/persistable/incrementable.rb +36 -0
  93. data/lib/mongoid/persistable/logical.rb +38 -0
  94. data/lib/mongoid/persistable/poppable.rb +39 -0
  95. data/lib/mongoid/persistable/pullable.rb +55 -0
  96. data/lib/mongoid/persistable/pushable.rb +62 -0
  97. data/lib/mongoid/persistable/renamable.rb +35 -0
  98. data/lib/mongoid/persistable/savable.rb +52 -0
  99. data/lib/mongoid/persistable/settable.rb +33 -0
  100. data/lib/mongoid/persistable/unsettable.rb +36 -0
  101. data/lib/mongoid/persistable/updatable.rb +152 -0
  102. data/lib/mongoid/persistable/upsertable.rb +55 -0
  103. data/lib/mongoid/persistable.rb +216 -0
  104. data/lib/mongoid/positional.rb +71 -0
  105. data/lib/mongoid/query_cache.rb +247 -0
  106. data/lib/mongoid/railtie.rb +32 -45
  107. data/lib/mongoid/railties/database.rake +9 -25
  108. data/lib/mongoid/relations/accessors.rb +13 -49
  109. data/lib/mongoid/relations/auto_save.rb +15 -36
  110. data/lib/mongoid/relations/binding.rb +1 -24
  111. data/lib/mongoid/relations/bindings/embedded/in.rb +1 -1
  112. data/lib/mongoid/relations/bindings/embedded/many.rb +1 -3
  113. data/lib/mongoid/relations/bindings/referenced/in.rb +3 -8
  114. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +3 -1
  115. data/lib/mongoid/relations/builder.rb +1 -1
  116. data/lib/mongoid/relations/builders/nested_attributes/many.rb +10 -13
  117. data/lib/mongoid/relations/builders/nested_attributes/one.rb +4 -5
  118. data/lib/mongoid/relations/builders/referenced/in.rb +1 -1
  119. data/lib/mongoid/relations/builders/referenced/many.rb +1 -2
  120. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +1 -2
  121. data/lib/mongoid/relations/builders/referenced/one.rb +1 -1
  122. data/lib/mongoid/relations/builders.rb +2 -2
  123. data/lib/mongoid/relations/cascading.rb +3 -5
  124. data/lib/mongoid/relations/constraint.rb +1 -1
  125. data/lib/mongoid/relations/conversions.rb +1 -1
  126. data/lib/mongoid/relations/counter_cache.rb +39 -15
  127. data/lib/mongoid/relations/eager/base.rb +149 -0
  128. data/lib/mongoid/relations/eager/belongs_to.rb +31 -0
  129. data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +47 -0
  130. data/lib/mongoid/relations/eager/has_many.rb +38 -0
  131. data/lib/mongoid/relations/eager/has_one.rb +30 -0
  132. data/lib/mongoid/relations/eager.rb +46 -0
  133. data/lib/mongoid/relations/embedded/batchable.rb +4 -5
  134. data/lib/mongoid/relations/embedded/in.rb +4 -4
  135. data/lib/mongoid/relations/embedded/many.rb +14 -32
  136. data/lib/mongoid/relations/embedded/one.rb +1 -1
  137. data/lib/mongoid/relations/macros.rb +3 -4
  138. data/lib/mongoid/relations/many.rb +30 -31
  139. data/lib/mongoid/relations/marshalable.rb +3 -3
  140. data/lib/mongoid/relations/metadata.rb +14 -79
  141. data/lib/mongoid/relations/nested_builder.rb +2 -2
  142. data/lib/mongoid/relations/options.rb +1 -0
  143. data/lib/mongoid/relations/polymorphic.rb +0 -1
  144. data/lib/mongoid/relations/proxy.rb +21 -41
  145. data/lib/mongoid/relations/referenced/in.rb +4 -20
  146. data/lib/mongoid/relations/referenced/many.rb +19 -32
  147. data/lib/mongoid/relations/referenced/many_to_many.rb +15 -38
  148. data/lib/mongoid/relations/referenced/one.rb +6 -25
  149. data/lib/mongoid/relations/synchronization.rb +3 -3
  150. data/lib/mongoid/relations/touchable.rb +34 -1
  151. data/lib/mongoid/relations.rb +11 -25
  152. data/lib/mongoid/{reloading.rb → reloadable.rb} +6 -4
  153. data/lib/mongoid/{scoping.rb → scopable.rb} +36 -36
  154. data/lib/mongoid/selectable.rb +59 -0
  155. data/lib/mongoid/{serialization.rb → serializable.rb} +11 -2
  156. data/lib/mongoid/sessions/factory.rb +2 -0
  157. data/lib/mongoid/sessions/options.rb +180 -0
  158. data/lib/mongoid/sessions/storage_options.rb +140 -0
  159. data/lib/mongoid/sessions/thread_options.rb +19 -0
  160. data/lib/mongoid/sessions/validators/storage.rb +16 -3
  161. data/lib/mongoid/sessions.rb +37 -345
  162. data/lib/mongoid/{sharding.rb → shardable.rb} +5 -1
  163. data/lib/mongoid/{state.rb → stateful.rb} +13 -1
  164. data/lib/mongoid/support/query_counter.rb +23 -0
  165. data/lib/mongoid/tasks/database.rake +31 -0
  166. data/lib/mongoid/tasks/database.rb +107 -0
  167. data/lib/mongoid/threaded/lifecycle.rb +0 -28
  168. data/lib/mongoid/threaded.rb +0 -157
  169. data/lib/mongoid/timestamps/updated/short.rb +2 -2
  170. data/lib/mongoid/{hierarchy.rb → traversable.rb} +9 -5
  171. data/lib/mongoid/{validations → validatable}/associated.rb +4 -2
  172. data/lib/mongoid/{validations → validatable}/format.rb +1 -1
  173. data/lib/mongoid/{validations → validatable}/length.rb +1 -1
  174. data/lib/mongoid/{validations → validatable}/localizable.rb +1 -1
  175. data/lib/mongoid/{validations → validatable}/macros.rb +4 -3
  176. data/lib/mongoid/{validations → validatable}/presence.rb +1 -1
  177. data/lib/mongoid/{validations → validatable}/queryable.rb +1 -2
  178. data/lib/mongoid/{validations → validatable}/uniqueness.rb +23 -19
  179. data/lib/mongoid/{validations.rb → validatable.rb} +23 -10
  180. data/lib/mongoid/version.rb +1 -1
  181. data/lib/mongoid.rb +10 -76
  182. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +13 -24
  183. data/lib/rails/generators/mongoid/model/model_generator.rb +0 -1
  184. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +0 -3
  185. data/lib/rails/generators/mongoid_generator.rb +3 -40
  186. data/lib/rails/mongoid.rb +0 -122
  187. data/lib/support/ruby_version.rb +1 -1
  188. data/spec/app/models/account.rb +2 -6
  189. data/spec/app/models/acolyte.rb +2 -1
  190. data/spec/app/models/actor.rb +0 -1
  191. data/spec/app/models/address.rb +8 -3
  192. data/spec/app/models/animal.rb +1 -1
  193. data/spec/app/models/appointment.rb +3 -3
  194. data/spec/app/models/article.rb +1 -4
  195. data/spec/app/models/audio.rb +5 -0
  196. data/spec/app/models/author.rb +0 -2
  197. data/spec/app/models/band.rb +3 -2
  198. data/spec/app/models/bar.rb +1 -0
  199. data/spec/app/models/book.rb +1 -0
  200. data/spec/app/models/building.rb +0 -2
  201. data/spec/app/models/building_address.rb +0 -2
  202. data/spec/app/models/bus.rb +1 -1
  203. data/spec/app/models/canvas.rb +1 -1
  204. data/spec/app/models/contractor.rb +0 -2
  205. data/spec/app/models/country_code.rb +1 -1
  206. data/spec/app/models/definition.rb +2 -2
  207. data/spec/app/models/dog.rb +1 -1
  208. data/spec/app/models/draft.rb +9 -0
  209. data/spec/app/models/dragon.rb +4 -0
  210. data/spec/app/models/drug.rb +1 -3
  211. data/spec/app/models/dungeon.rb +4 -0
  212. data/spec/app/models/edit.rb +5 -0
  213. data/spec/app/models/even.rb +7 -0
  214. data/spec/app/models/event.rb +1 -1
  215. data/spec/app/models/filesystem.rb +1 -0
  216. data/spec/app/models/fish.rb +0 -1
  217. data/spec/app/models/fruits.rb +6 -0
  218. data/spec/app/models/game.rb +0 -2
  219. data/spec/app/models/house.rb +1 -3
  220. data/spec/app/models/item.rb +1 -5
  221. data/spec/app/models/jar.rb +1 -1
  222. data/spec/app/models/label.rb +4 -4
  223. data/spec/app/models/line_item.rb +1 -1
  224. data/spec/app/models/login.rb +1 -1
  225. data/spec/app/models/message.rb +8 -0
  226. data/spec/app/models/movie.rb +1 -0
  227. data/spec/app/models/name.rb +3 -3
  228. data/spec/app/models/note.rb +3 -1
  229. data/spec/app/models/odd.rb +7 -0
  230. data/spec/app/models/oscar.rb +1 -1
  231. data/spec/app/models/parent_doc.rb +1 -1
  232. data/spec/app/models/person.rb +16 -10
  233. data/spec/app/models/phone.rb +1 -3
  234. data/spec/app/models/player.rb +3 -3
  235. data/spec/app/models/post.rb +5 -3
  236. data/spec/app/models/preference.rb +1 -1
  237. data/spec/app/models/quiz.rb +0 -3
  238. data/spec/app/models/record.rb +10 -5
  239. data/spec/app/models/registry.rb +1 -1
  240. data/spec/app/models/server.rb +1 -1
  241. data/spec/app/models/service.rb +3 -3
  242. data/spec/app/models/sound.rb +5 -0
  243. data/spec/app/models/symptom.rb +1 -1
  244. data/spec/app/models/template.rb +1 -1
  245. data/spec/app/models/title.rb +0 -1
  246. data/spec/app/models/track.rb +5 -5
  247. data/spec/app/models/tree.rb +3 -3
  248. data/spec/app/models/video.rb +1 -5
  249. data/spec/app/models/wiki_page.rb +2 -5
  250. data/spec/app/models/word.rb +3 -0
  251. data/spec/app/models/word_origin.rb +1 -1
  252. data/spec/config/mongoid.yml +7 -8
  253. data/spec/helpers.rb +18 -0
  254. data/spec/mongoid/atomic/modifiers_spec.rb +22 -22
  255. data/spec/mongoid/atomic/paths/embedded/many_spec.rb +8 -49
  256. data/spec/mongoid/atomic/paths/embedded/one_spec.rb +7 -49
  257. data/spec/mongoid/atomic/paths/root_spec.rb +3 -61
  258. data/spec/mongoid/atomic/paths_spec.rb +19 -19
  259. data/spec/mongoid/atomic_spec.rb +19 -19
  260. data/spec/mongoid/{nested_attributes_spec.rb → attributes/nested_spec.rb} +335 -448
  261. data/spec/mongoid/attributes/readonly_spec.rb +58 -18
  262. data/spec/mongoid/attributes_spec.rb +315 -436
  263. data/spec/mongoid/{dirty_spec.rb → changeable_spec.rb} +203 -153
  264. data/spec/mongoid/{components_spec.rb → composable_spec.rb} +3 -3
  265. data/spec/mongoid/config/environment_spec.rb +3 -3
  266. data/spec/mongoid/config/options_spec.rb +6 -6
  267. data/spec/mongoid/config_spec.rb +24 -48
  268. data/spec/mongoid/contextual/aggregable/memory_spec.rb +12 -12
  269. data/spec/mongoid/contextual/aggregable/mongo_spec.rb +78 -38
  270. data/spec/mongoid/contextual/atomic_spec.rb +68 -58
  271. data/spec/mongoid/contextual/find_and_modify_spec.rb +14 -14
  272. data/spec/mongoid/contextual/geo_near_spec.rb +22 -22
  273. data/spec/mongoid/contextual/map_reduce_spec.rb +27 -27
  274. data/spec/mongoid/contextual/memory_spec.rb +151 -94
  275. data/spec/mongoid/contextual/mongo_spec.rb +238 -150
  276. data/spec/mongoid/contextual/none_spec.rb +127 -0
  277. data/spec/mongoid/contextual/text_search_spec.rb +209 -0
  278. data/spec/mongoid/copyable_spec.rb +56 -68
  279. data/spec/mongoid/criteria/findable_spec.rb +991 -0
  280. data/spec/mongoid/{criterion/inspection_spec.rb → criteria/inspectable_spec.rb} +5 -5
  281. data/spec/mongoid/{criterion → criteria}/marshalable_spec.rb +2 -2
  282. data/spec/mongoid/criteria/modifiable_spec.rb +1255 -0
  283. data/spec/mongoid/{criterion/scoping_spec.rb → criteria/scopable_spec.rb} +37 -37
  284. data/spec/mongoid/criteria_spec.rb +578 -2295
  285. data/spec/mongoid/document_spec.rb +166 -120
  286. data/spec/mongoid/equality_spec.rb +22 -22
  287. data/spec/mongoid/errors/ambiguous_relationship_spec.rb +3 -3
  288. data/spec/mongoid/errors/callback_spec.rb +3 -3
  289. data/spec/mongoid/errors/delete_restriction_spec.rb +3 -3
  290. data/spec/mongoid/errors/document_not_destroyed_spec.rb +33 -0
  291. data/spec/mongoid/errors/document_not_found_spec.rb +11 -11
  292. data/spec/mongoid/errors/eager_load_spec.rb +3 -3
  293. data/spec/mongoid/errors/invalid_collection_spec.rb +3 -3
  294. data/spec/mongoid/errors/invalid_config_option_spec.rb +3 -3
  295. data/spec/mongoid/errors/invalid_field_option_spec.rb +3 -3
  296. data/spec/mongoid/errors/invalid_field_spec.rb +3 -3
  297. data/spec/mongoid/errors/invalid_find_spec.rb +3 -3
  298. data/spec/mongoid/errors/invalid_includes_spec.rb +3 -3
  299. data/spec/mongoid/errors/invalid_index_spec.rb +3 -3
  300. data/spec/mongoid/errors/invalid_options_spec.rb +3 -3
  301. data/spec/mongoid/errors/invalid_path_spec.rb +3 -3
  302. data/spec/mongoid/errors/invalid_scope_spec.rb +5 -5
  303. data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +3 -3
  304. data/spec/mongoid/errors/invalid_storage_options_spec.rb +3 -3
  305. data/spec/mongoid/errors/invalid_time_spec.rb +3 -3
  306. data/spec/mongoid/errors/inverse_not_found_spec.rb +3 -3
  307. data/spec/mongoid/errors/mixed_relations_spec.rb +3 -3
  308. data/spec/mongoid/errors/mixed_session_configuration_spec.rb +3 -3
  309. data/spec/mongoid/errors/mongoid_error_spec.rb +8 -8
  310. data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +3 -3
  311. data/spec/mongoid/errors/no_environment_spec.rb +3 -3
  312. data/spec/mongoid/errors/no_map_reduce_output_spec.rb +3 -3
  313. data/spec/mongoid/errors/no_metadata_spec.rb +3 -3
  314. data/spec/mongoid/errors/no_parent_spec.rb +3 -3
  315. data/spec/mongoid/errors/no_session_config_spec.rb +3 -3
  316. data/spec/mongoid/errors/no_session_database_spec.rb +3 -3
  317. data/spec/mongoid/errors/no_session_hosts_spec.rb +3 -3
  318. data/spec/mongoid/errors/no_sessions_config_spec.rb +3 -3
  319. data/spec/mongoid/errors/readonly_attribute_spec.rb +3 -3
  320. data/spec/mongoid/errors/readonly_document_spec.rb +29 -0
  321. data/spec/mongoid/errors/scope_overwrite_spec.rb +3 -3
  322. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +3 -3
  323. data/spec/mongoid/errors/unknown_attribute_spec.rb +5 -5
  324. data/spec/mongoid/errors/unsaved_document_spec.rb +3 -3
  325. data/spec/mongoid/errors/unsupported_javascript_spec.rb +3 -3
  326. data/spec/mongoid/errors/validations_spec.rb +7 -7
  327. data/spec/mongoid/extensions/array_spec.rb +61 -61
  328. data/spec/mongoid/extensions/big_decimal_spec.rb +11 -11
  329. data/spec/mongoid/extensions/binary_spec.rb +12 -12
  330. data/spec/mongoid/extensions/boolean_spec.rb +18 -18
  331. data/spec/mongoid/extensions/date_spec.rb +13 -13
  332. data/spec/mongoid/extensions/date_time_spec.rb +8 -8
  333. data/spec/mongoid/extensions/false_class_spec.rb +5 -5
  334. data/spec/mongoid/extensions/float_spec.rb +29 -15
  335. data/spec/mongoid/extensions/hash_spec.rb +29 -29
  336. data/spec/mongoid/extensions/integer_spec.rb +15 -15
  337. data/spec/mongoid/extensions/module_spec.rb +2 -2
  338. data/spec/mongoid/extensions/nil_class_spec.rb +1 -1
  339. data/spec/mongoid/extensions/object_id_spec.rb +134 -134
  340. data/spec/mongoid/extensions/object_spec.rb +26 -26
  341. data/spec/mongoid/extensions/range_spec.rb +61 -12
  342. data/spec/mongoid/extensions/regexp_spec.rb +4 -4
  343. data/spec/mongoid/extensions/set_spec.rb +4 -4
  344. data/spec/mongoid/extensions/string_spec.rb +35 -46
  345. data/spec/mongoid/extensions/symbol_spec.rb +9 -9
  346. data/spec/mongoid/extensions/time_spec.rb +49 -49
  347. data/spec/mongoid/extensions/time_with_zone_spec.rb +34 -34
  348. data/spec/mongoid/extensions/true_class_spec.rb +5 -5
  349. data/spec/mongoid/extensions_spec.rb +15 -0
  350. data/spec/mongoid/factory_spec.rb +15 -15
  351. data/spec/mongoid/fields/foreign_key_spec.rb +73 -66
  352. data/spec/mongoid/fields/internal/foreign_keys/array_spec.rb +15 -15
  353. data/spec/mongoid/fields/internal/foreign_keys/object_spec.rb +22 -22
  354. data/spec/mongoid/fields/localized_spec.rb +38 -23
  355. data/spec/mongoid/fields/standard_spec.rb +12 -12
  356. data/spec/mongoid/fields_spec.rb +263 -217
  357. data/spec/mongoid/{finders_spec.rb → findable_spec.rb} +127 -27
  358. data/spec/mongoid/indexable/specification_spec.rb +102 -0
  359. data/spec/mongoid/{indexes_spec.rb → indexable_spec.rb} +171 -51
  360. data/spec/mongoid/{inspection_spec.rb → inspectable_spec.rb} +6 -14
  361. data/spec/mongoid/{callbacks_spec.rb → interceptable_spec.rb} +117 -116
  362. data/spec/mongoid/log_subscriber_spec.rb +75 -0
  363. data/spec/mongoid/loggable_spec.rb +1 -1
  364. data/spec/mongoid/{matchers → matchable}/all_spec.rb +4 -4
  365. data/spec/mongoid/{matchers → matchable}/and_spec.rb +11 -11
  366. data/spec/mongoid/{matchers → matchable}/default_spec.rb +15 -15
  367. data/spec/mongoid/{matchers → matchable}/exists_spec.rb +5 -5
  368. data/spec/mongoid/{matchers → matchable}/gt_spec.rb +9 -8
  369. data/spec/mongoid/{matchers → matchable}/gte_spec.rb +7 -7
  370. data/spec/mongoid/matchable/in_spec.rb +49 -0
  371. data/spec/mongoid/{matchers → matchable}/lt_spec.rb +7 -7
  372. data/spec/mongoid/{matchers → matchable}/lte_spec.rb +7 -7
  373. data/spec/mongoid/matchable/ne_spec.rb +46 -0
  374. data/spec/mongoid/matchable/nin_spec.rb +48 -0
  375. data/spec/mongoid/{matchers → matchable}/or_spec.rb +6 -6
  376. data/spec/mongoid/{matchers → matchable}/size_spec.rb +3 -3
  377. data/spec/mongoid/{matchers_spec.rb → matchable_spec.rb} +41 -41
  378. data/spec/mongoid/persistable/creatable_spec.rb +512 -0
  379. data/spec/mongoid/persistable/deletable_spec.rb +218 -0
  380. data/spec/mongoid/persistable/destroyable_spec.rb +192 -0
  381. data/spec/mongoid/persistable/incrementable_spec.rb +173 -0
  382. data/spec/mongoid/persistable/logical_spec.rb +143 -0
  383. data/spec/mongoid/persistable/poppable_spec.rb +115 -0
  384. data/spec/mongoid/persistable/pullable_spec.rb +228 -0
  385. data/spec/mongoid/persistable/pushable_spec.rb +258 -0
  386. data/spec/mongoid/persistable/renamable_spec.rb +135 -0
  387. data/spec/mongoid/persistable/savable_spec.rb +461 -0
  388. data/spec/mongoid/persistable/settable_spec.rb +139 -0
  389. data/spec/mongoid/persistable/unsettable_spec.rb +155 -0
  390. data/spec/mongoid/persistable/updatable_spec.rb +558 -0
  391. data/spec/mongoid/persistable/upsertable_spec.rb +106 -0
  392. data/spec/mongoid/persistable_spec.rb +206 -0
  393. data/spec/mongoid/{atomic/positionable_spec.rb → positional_spec.rb} +9 -9
  394. data/spec/mongoid/query_cache_spec.rb +231 -0
  395. data/spec/mongoid/railties/document_spec.rb +2 -2
  396. data/spec/mongoid/relations/accessors_spec.rb +53 -145
  397. data/spec/mongoid/relations/auto_save_spec.rb +37 -17
  398. data/spec/mongoid/relations/bindings/embedded/in_spec.rb +12 -12
  399. data/spec/mongoid/relations/bindings/embedded/many_spec.rb +3 -3
  400. data/spec/mongoid/relations/bindings/embedded/one_spec.rb +5 -5
  401. data/spec/mongoid/relations/bindings/referenced/in_spec.rb +26 -26
  402. data/spec/mongoid/relations/bindings/referenced/many_spec.rb +10 -10
  403. data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +19 -19
  404. data/spec/mongoid/relations/bindings/referenced/one_spec.rb +12 -12
  405. data/spec/mongoid/relations/builders/embedded/in_spec.rb +4 -4
  406. data/spec/mongoid/relations/builders/embedded/many_spec.rb +18 -18
  407. data/spec/mongoid/relations/builders/embedded/one_spec.rb +11 -11
  408. data/spec/mongoid/relations/builders/nested_attributes/many_spec.rb +12 -13
  409. data/spec/mongoid/relations/builders/nested_attributes/one_spec.rb +14 -14
  410. data/spec/mongoid/relations/builders/referenced/in_spec.rb +24 -35
  411. data/spec/mongoid/relations/builders/referenced/many_spec.rb +15 -15
  412. data/spec/mongoid/relations/builders/referenced/many_to_many_spec.rb +18 -18
  413. data/spec/mongoid/relations/builders/referenced/one_spec.rb +12 -25
  414. data/spec/mongoid/relations/builders_spec.rb +21 -21
  415. data/spec/mongoid/relations/cascading/delete_spec.rb +9 -9
  416. data/spec/mongoid/relations/cascading/destroy_spec.rb +6 -6
  417. data/spec/mongoid/relations/cascading/nullify_spec.rb +4 -4
  418. data/spec/mongoid/relations/cascading/restrict_spec.rb +7 -7
  419. data/spec/mongoid/relations/cascading_spec.rb +16 -16
  420. data/spec/mongoid/relations/constraint_spec.rb +8 -7
  421. data/spec/mongoid/relations/conversions_spec.rb +16 -14
  422. data/spec/mongoid/relations/counter_cache_spec.rb +85 -0
  423. data/spec/mongoid/relations/cyclic_spec.rb +18 -18
  424. data/spec/mongoid/relations/eager/belongs_to_spec.rb +154 -0
  425. data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +117 -0
  426. data/spec/mongoid/relations/eager/has_many_spec.rb +207 -0
  427. data/spec/mongoid/relations/eager/has_one_spec.rb +163 -0
  428. data/spec/mongoid/relations/eager_spec.rb +228 -0
  429. data/spec/mongoid/relations/embedded/dirty_spec.rb +8 -8
  430. data/spec/mongoid/relations/embedded/in_spec.rb +56 -57
  431. data/spec/mongoid/relations/embedded/many_spec.rb +393 -372
  432. data/spec/mongoid/relations/embedded/one_spec.rb +108 -141
  433. data/spec/mongoid/relations/macros_spec.rb +108 -102
  434. data/spec/mongoid/relations/metadata_spec.rb +180 -255
  435. data/spec/mongoid/relations/options_spec.rb +1 -1
  436. data/spec/mongoid/relations/polymorphic_spec.rb +13 -17
  437. data/spec/mongoid/relations/proxy_spec.rb +2 -2
  438. data/spec/mongoid/relations/referenced/in_spec.rb +128 -303
  439. data/spec/mongoid/relations/referenced/many_spec.rb +434 -527
  440. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +352 -424
  441. data/spec/mongoid/relations/referenced/one_spec.rb +149 -264
  442. data/spec/mongoid/relations/reflections_spec.rb +6 -6
  443. data/spec/mongoid/relations/synchronization_spec.rb +46 -50
  444. data/spec/mongoid/relations/targets/enumerable_spec.rb +118 -118
  445. data/spec/mongoid/relations/touchable_spec.rb +333 -0
  446. data/spec/mongoid/relations_spec.rb +16 -15
  447. data/spec/mongoid/{reloading_spec.rb → reloadable_spec.rb} +20 -60
  448. data/spec/mongoid/{scoping_spec.rb → scopable_spec.rb} +89 -164
  449. data/spec/mongoid/selectable_spec.rb +134 -0
  450. data/spec/mongoid/{serialization_spec.rb → serializable_spec.rb} +129 -82
  451. data/spec/mongoid/sessions/factory_spec.rb +49 -28
  452. data/spec/mongoid/sessions/mongo_uri_spec.rb +7 -7
  453. data/spec/mongoid/sessions/options_spec.rb +107 -0
  454. data/spec/mongoid/sessions_spec.rb +289 -178
  455. data/spec/mongoid/{sharding_spec.rb → shardable_spec.rb} +8 -8
  456. data/spec/mongoid/{state_spec.rb → stateful_spec.rb} +36 -11
  457. data/spec/mongoid/tasks/database_rake_spec.rb +285 -0
  458. data/spec/mongoid/tasks/database_spec.rb +160 -0
  459. data/spec/mongoid/threaded_spec.rb +17 -70
  460. data/spec/mongoid/timestamps/created/short_spec.rb +6 -6
  461. data/spec/mongoid/timestamps/created_spec.rb +5 -5
  462. data/spec/mongoid/timestamps/timeless_spec.rb +6 -6
  463. data/spec/mongoid/timestamps/updated/short_spec.rb +11 -11
  464. data/spec/mongoid/timestamps/updated_spec.rb +9 -13
  465. data/spec/mongoid/timestamps_spec.rb +9 -13
  466. data/spec/mongoid/{hierarchy_spec.rb → traversable_spec.rb} +19 -19
  467. data/spec/mongoid/{validations → validatable}/associated_spec.rb +45 -22
  468. data/spec/mongoid/{validations → validatable}/format_spec.rb +6 -6
  469. data/spec/mongoid/{validations → validatable}/length_spec.rb +14 -14
  470. data/spec/mongoid/{validations → validatable}/numericality_spec.rb +1 -1
  471. data/spec/mongoid/{validations → validatable}/presence_spec.rb +37 -44
  472. data/spec/mongoid/{validations → validatable}/uniqueness_spec.rb +184 -192
  473. data/spec/mongoid/{validations_spec.rb → validatable_spec.rb} +28 -28
  474. data/spec/mongoid_spec.rb +8 -8
  475. data/spec/rails/mongoid_spec.rb +19 -335
  476. data/spec/spec_helper.rb +29 -13
  477. metadata +296 -283
  478. data/lib/mongoid/atomic/positionable.rb +0 -73
  479. data/lib/mongoid/components.rb +0 -92
  480. data/lib/mongoid/config/inflections.rb +0 -6
  481. data/lib/mongoid/contextual/eager.rb +0 -158
  482. data/lib/mongoid/errors/versioning_not_on_root.rb +0 -23
  483. data/lib/mongoid/identity_map.rb +0 -163
  484. data/lib/mongoid/json.rb +0 -16
  485. data/lib/mongoid/matchers/strategies.rb +0 -97
  486. data/lib/mongoid/matchers.rb +0 -32
  487. data/lib/mongoid/multi_parameter_attributes.rb +0 -105
  488. data/lib/mongoid/nested_attributes.rb +0 -78
  489. data/lib/mongoid/observer.rb +0 -192
  490. data/lib/mongoid/paranoia.rb +0 -136
  491. data/lib/mongoid/persistence/atomic/add_to_set.rb +0 -47
  492. data/lib/mongoid/persistence/atomic/bit.rb +0 -35
  493. data/lib/mongoid/persistence/atomic/inc.rb +0 -45
  494. data/lib/mongoid/persistence/atomic/operation.rb +0 -154
  495. data/lib/mongoid/persistence/atomic/pop.rb +0 -32
  496. data/lib/mongoid/persistence/atomic/pull.rb +0 -32
  497. data/lib/mongoid/persistence/atomic/pull_all.rb +0 -32
  498. data/lib/mongoid/persistence/atomic/push.rb +0 -25
  499. data/lib/mongoid/persistence/atomic/push_all.rb +0 -25
  500. data/lib/mongoid/persistence/atomic/rename.rb +0 -30
  501. data/lib/mongoid/persistence/atomic/sets.rb +0 -28
  502. data/lib/mongoid/persistence/atomic/unset.rb +0 -27
  503. data/lib/mongoid/persistence/atomic.rb +0 -231
  504. data/lib/mongoid/persistence/deletion.rb +0 -31
  505. data/lib/mongoid/persistence/insertion.rb +0 -38
  506. data/lib/mongoid/persistence/modification.rb +0 -35
  507. data/lib/mongoid/persistence/operations/embedded/insert.rb +0 -46
  508. data/lib/mongoid/persistence/operations/embedded/remove.rb +0 -43
  509. data/lib/mongoid/persistence/operations/insert.rb +0 -34
  510. data/lib/mongoid/persistence/operations/remove.rb +0 -33
  511. data/lib/mongoid/persistence/operations/update.rb +0 -59
  512. data/lib/mongoid/persistence/operations/upsert.rb +0 -28
  513. data/lib/mongoid/persistence/operations.rb +0 -214
  514. data/lib/mongoid/persistence/upsertion.rb +0 -31
  515. data/lib/mongoid/persistence.rb +0 -357
  516. data/lib/mongoid/unit_of_work.rb +0 -61
  517. data/lib/mongoid/versioning.rb +0 -217
  518. data/lib/rack/mongoid/middleware/identity_map.rb +0 -39
  519. data/lib/rack/mongoid.rb +0 -2
  520. data/lib/rails/generators/mongoid/observer/observer_generator.rb +0 -17
  521. data/lib/rails/generators/mongoid/observer/templates/observer.rb.tt +0 -4
  522. data/spec/app/models/actor_observer.rb +0 -15
  523. data/spec/app/models/callback_recorder.rb +0 -25
  524. data/spec/app/models/paranoid_phone.rb +0 -25
  525. data/spec/app/models/paranoid_post.rb +0 -36
  526. data/spec/app/models/phone_observer.rb +0 -6
  527. data/spec/mongoid/attributes/processing_spec.rb +0 -149
  528. data/spec/mongoid/criterion/destructive_spec.rb +0 -101
  529. data/spec/mongoid/criterion/modifiable_spec.rb +0 -409
  530. data/spec/mongoid/criterion/modification_spec.rb +0 -402
  531. data/spec/mongoid/errors/versioning_not_on_root_spec.rb +0 -29
  532. data/spec/mongoid/identity_map_spec.rb +0 -564
  533. data/spec/mongoid/json_spec.rb +0 -33
  534. data/spec/mongoid/matchers/in_spec.rb +0 -25
  535. data/spec/mongoid/matchers/ne_spec.rb +0 -25
  536. data/spec/mongoid/matchers/nin_spec.rb +0 -25
  537. data/spec/mongoid/multi_parameter_attributes_spec.rb +0 -128
  538. data/spec/mongoid/observer_spec.rb +0 -290
  539. data/spec/mongoid/paranoia_spec.rb +0 -759
  540. data/spec/mongoid/persistence/atomic/add_to_set_spec.rb +0 -262
  541. data/spec/mongoid/persistence/atomic/bit_spec.rb +0 -88
  542. data/spec/mongoid/persistence/atomic/inc_spec.rb +0 -133
  543. data/spec/mongoid/persistence/atomic/pop_spec.rb +0 -111
  544. data/spec/mongoid/persistence/atomic/pull_all_spec.rb +0 -77
  545. data/spec/mongoid/persistence/atomic/pull_spec.rb +0 -80
  546. data/spec/mongoid/persistence/atomic/push_all_spec.rb +0 -77
  547. data/spec/mongoid/persistence/atomic/push_spec.rb +0 -77
  548. data/spec/mongoid/persistence/atomic/rename_spec.rb +0 -42
  549. data/spec/mongoid/persistence/atomic/sets_spec.rb +0 -154
  550. data/spec/mongoid/persistence/atomic/unset_spec.rb +0 -65
  551. data/spec/mongoid/persistence/atomic_spec.rb +0 -216
  552. data/spec/mongoid/persistence/operations/embedded/insert_spec.rb +0 -191
  553. data/spec/mongoid/persistence/operations/embedded/remove_spec.rb +0 -8
  554. data/spec/mongoid/persistence/operations/insert_spec.rb +0 -149
  555. data/spec/mongoid/persistence/operations/remove_spec.rb +0 -113
  556. data/spec/mongoid/persistence/operations/update_spec.rb +0 -141
  557. data/spec/mongoid/persistence/operations/upsert_spec.rb +0 -59
  558. data/spec/mongoid/persistence/operations_spec.rb +0 -313
  559. data/spec/mongoid/persistence_spec.rb +0 -2279
  560. data/spec/mongoid/unit_of_work_spec.rb +0 -196
  561. data/spec/mongoid/versioning_spec.rb +0 -540
  562. data/spec/rack/mongoid/middleware/identity_map_spec.rb +0 -72
@@ -0,0 +1,117 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Relations::Eager::HasAndBelongsToMany do
4
+
5
+ describe ".keys_from_docs" do
6
+
7
+ let(:docs) do
8
+ Person.all.to_a
9
+ end
10
+
11
+ let!(:person) do
12
+ Person.create!(houses: [house])
13
+ end
14
+
15
+ let!(:house) do
16
+ House.create!
17
+ end
18
+
19
+ let(:metadata) do
20
+ Person.reflect_on_association(:houses)
21
+ end
22
+
23
+ let(:eager) do
24
+ described_class.new([metadata], docs).tap do |b|
25
+ b.shift_metadata
26
+ end
27
+ end
28
+
29
+ it "aggregates by the foreign key" do
30
+ expect(eager.keys_from_docs).to eq([house.id])
31
+ end
32
+ end
33
+
34
+ describe ".includes" do
35
+
36
+ let(:person) do
37
+ Person.create!
38
+ end
39
+
40
+ before do
41
+ Person.create!(houses: 3.times.map { House.create! })
42
+ end
43
+
44
+ context "when including the has_and_belongs_to_many relation" do
45
+
46
+ it "queries twice" do
47
+ expect_query(2) do
48
+ Person.all.includes(:houses).each do |person|
49
+ expect(person.houses).to_not be_nil
50
+
51
+ expect(person.houses.length).to be(3)
52
+ end
53
+ end
54
+ end
55
+
56
+ it "has all items" do
57
+ Person.all.includes(:houses).each do |person|
58
+ expect(person.ivar(:houses).length).to be(3)
59
+ end
60
+ end
61
+ end
62
+
63
+ context "when the relation is not polymorphic" do
64
+
65
+ let(:eager) do
66
+ Person.includes(:preferences).last
67
+ end
68
+
69
+ context "when the eager load has returned documents" do
70
+
71
+ let!(:preference) do
72
+ person.preferences.create(name: "testing")
73
+ end
74
+
75
+ before { eager }
76
+
77
+ it "puts the documents in the parent document" do
78
+ expect(eager.ivar(:preferences)).to eq([ preference ])
79
+ end
80
+
81
+ it "does not query when touching the association" do
82
+ expect_query(0) do
83
+ expect(eager.preferences).to eq([ preference ])
84
+ end
85
+ end
86
+
87
+ it "does not query when updating the association" do
88
+ expect_query(0) do
89
+ eager.preferences.first.name = "new pref"
90
+ expect(eager.preferences.first.name).to eq("new pref")
91
+ end
92
+ end
93
+ end
94
+
95
+ context "when the eager load has not returned documents" do
96
+
97
+ before { eager }
98
+
99
+ it "has an empty proxy" do
100
+ expect(eager.preferences).to eq []
101
+ end
102
+
103
+ it "does not query when touching the association" do
104
+ expect_query(0) do
105
+ eager.preferences.entries
106
+ end
107
+ end
108
+
109
+ it "returns the proxy" do
110
+ expect do
111
+ eager.preferences.create(name: "testing")
112
+ end.to_not raise_error
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,207 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Relations::Eager::HasMany do
4
+
5
+ describe ".grouped_docs" do
6
+
7
+ let(:docs) do
8
+ Person.all.to_a
9
+ end
10
+
11
+ let(:person) do
12
+ Person.create!
13
+ end
14
+
15
+ let(:metadata) do
16
+ Person.reflect_on_association(:posts)
17
+ end
18
+
19
+ let(:eager) do
20
+ described_class.new([metadata], docs).tap do |b|
21
+ b.shift_metadata
22
+ end
23
+ end
24
+
25
+ before do
26
+ Post.create!(person: person)
27
+ end
28
+
29
+ it "aggregates by the parent primary key" do
30
+ expect(eager.grouped_docs.keys).to eq([person.id])
31
+ end
32
+ end
33
+
34
+ describe ".set_on_parent" do
35
+
36
+ let(:docs) do
37
+ Person.all.to_a
38
+ end
39
+
40
+ let(:person) do
41
+ Person.create!
42
+ end
43
+
44
+ let(:metadata) do
45
+ Person.reflect_on_association(:posts)
46
+ end
47
+
48
+ let(:eager) do
49
+ described_class.new([metadata], docs).tap do |b|
50
+ b.shift_metadata
51
+ end
52
+ end
53
+
54
+ before do
55
+ Post.create!(person: person)
56
+ eager
57
+ end
58
+
59
+ it "sets the relation into the parent" do
60
+ docs.each do |doc|
61
+ expect(doc).to receive(:__build__).once.with(:posts, :foo, metadata)
62
+ end
63
+ eager.set_on_parent(person.id, :foo)
64
+ end
65
+
66
+ it "doesnt call an extra query" do
67
+ expect_query(0) do
68
+ eager.set_on_parent(person.id, :foo)
69
+ end
70
+ end
71
+ end
72
+
73
+ describe ".includes" do
74
+
75
+ let(:person) do
76
+ Person.create!
77
+ end
78
+
79
+ context "when including the has_many relation" do
80
+
81
+ before do
82
+ 3.times { Drug.create!(person: person) }
83
+ Drug.create!(person: Person.create!)
84
+ end
85
+
86
+ it "queries twice" do
87
+
88
+ expect_query(2) do
89
+ Person.all.includes(:drugs).each do |person|
90
+ expect(person.drugs.entries).to_not be_empty
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ context "when the relation is not polymorphic" do
97
+
98
+ context "when the eager load has returned documents" do
99
+
100
+ let!(:post) do
101
+ person.posts.create(title: "testing")
102
+ end
103
+
104
+ let!(:eager) do
105
+ Person.includes(:posts).last
106
+ end
107
+
108
+ it "puts the documents in the parent document" do
109
+ expect(eager.ivar(:posts)).to eq([post])
110
+ end
111
+
112
+ it "does not query when touching the association" do
113
+ expect_query(0) do
114
+ expect(eager.posts).to eq([post])
115
+ end
116
+ end
117
+
118
+ it "does not query when updating the association" do
119
+ expect_query(0) do
120
+ eager.posts.first.title = "New title"
121
+ end
122
+ end
123
+ end
124
+
125
+ context "when the eager load has not returned documents" do
126
+
127
+ before { person }
128
+
129
+ let!(:eager) do
130
+ Person.includes(:posts).last
131
+ end
132
+
133
+ it "does not set anything on the parent" do
134
+ expect(eager.ivar(:posts)).to be_empty
135
+ end
136
+
137
+ it "has an empty proxy" do
138
+ expect(eager.posts).to eq([])
139
+ end
140
+
141
+ it "does not query when touching the association" do
142
+ expect_query(0) do
143
+ eager.posts.entries
144
+ end
145
+ end
146
+
147
+ it "returns the proxy" do
148
+ expect do
149
+ eager.posts.create(title: "testing")
150
+ end.to_not raise_error
151
+ end
152
+ end
153
+
154
+ context "when the eager load has not returned documents for some" do
155
+
156
+ let!(:person_one) do
157
+ person
158
+ end
159
+
160
+ let!(:person_two) do
161
+ Person.create(username: "durran")
162
+ end
163
+
164
+ let!(:post) do
165
+ person_one.posts.create(title: "testing")
166
+ end
167
+
168
+ let!(:eager) do
169
+ Person.includes(:posts).asc(:username).to_a
170
+ end
171
+
172
+ it "puts the found documents in the parent document" do
173
+ expect(eager.first.ivar(:posts)).to eq([post])
174
+ end
175
+
176
+ it "does not set documents not found" do
177
+ expect(eager.last.ivar(:posts)).to be_empty
178
+ end
179
+ end
180
+ end
181
+
182
+ context "when the relation is polymorphic" do
183
+
184
+ let!(:movie) do
185
+ Movie.create(name: "Bladerunner")
186
+ end
187
+
188
+ let!(:rating) do
189
+ movie.ratings.create(value: 10)
190
+ end
191
+
192
+ let!(:eager) do
193
+ Movie.includes(:ratings).first
194
+ end
195
+
196
+ it "puts the found documents in the parent document" do
197
+ expect(eager.ivar(:ratings)).to eq([rating])
198
+ end
199
+
200
+ it "does not query when touching the association" do
201
+ expect_query(0) do
202
+ expect(eager.ratings).to eq([rating])
203
+ end
204
+ end
205
+ end
206
+ end
207
+ end
@@ -0,0 +1,163 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Relations::Eager::HasOne do
4
+
5
+ describe ".grouped_doc" do
6
+
7
+ let(:person) do
8
+ Person.create!
9
+ end
10
+
11
+ let(:docs) do
12
+ Person.all.to_a
13
+ end
14
+
15
+ let(:metadata) do
16
+ Person.reflect_on_association(:cat)
17
+ end
18
+
19
+ let(:eager) do
20
+ described_class.new([metadata], docs).tap do |b|
21
+ b.shift_metadata
22
+ end
23
+ end
24
+
25
+ before do
26
+ Cat.create!(person: person)
27
+ end
28
+
29
+ it "aggregates by the relation primary key" do
30
+ expect(eager.grouped_docs.keys).to eq([person.username])
31
+ end
32
+ end
33
+
34
+ describe ".set_on_parent" do
35
+
36
+ let(:person) do
37
+ Person.create!
38
+ end
39
+
40
+ let(:docs) do
41
+ Person.all.to_a
42
+ end
43
+
44
+ let(:metadata) do
45
+ Person.reflect_on_association(:cat)
46
+ end
47
+
48
+ let(:eager) do
49
+ described_class.new([metadata], docs).tap do |b|
50
+ b.shift_metadata
51
+ end
52
+ end
53
+
54
+ before do
55
+ Cat.create!(person: person)
56
+ eager
57
+ end
58
+
59
+ it "sets the relation into the parent" do
60
+ docs.each do |doc|
61
+ expect(doc).to receive(:set_relation).once.with(:cat, :foo)
62
+ end
63
+ eager.set_on_parent(person.username, :foo)
64
+ end
65
+
66
+ it "doesnt call an extra query" do
67
+ expect_query(0) do
68
+ eager.set_on_parent(person.username, :foo)
69
+ end
70
+ end
71
+ end
72
+
73
+ describe ".includes" do
74
+
75
+ let(:person) do
76
+ Person.create!
77
+ end
78
+
79
+ before do
80
+ 3.times { Cat.create!(person: person) }
81
+ Cat.create!(person: Person.create!)
82
+ end
83
+
84
+ context "when including the has_one relation" do
85
+
86
+ it "queries twice" do
87
+
88
+ expect_query(2) do
89
+
90
+ Person.all.includes(:cat).each do |person|
91
+ expect(person.cat).to_not be_nil
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+ context "when including more than one has_one relation" do
98
+
99
+ it "queries 3 times" do
100
+
101
+ expect_query(3) do
102
+
103
+ Person.all.includes(:cat, :account).each do |person|
104
+ expect(person.cat).to_not be_nil
105
+ end
106
+ end
107
+ end
108
+ end
109
+
110
+ context "when the relation is not polymorphic" do
111
+
112
+ let!(:game) do
113
+ person.create_game(name: "Tron")
114
+ end
115
+
116
+ let!(:eager) do
117
+ Person.where(_id: person.id).includes(:game).first
118
+ end
119
+
120
+ it "puts the documents in the parent document" do
121
+ expect(eager.ivar(:game)).to eq(game)
122
+ end
123
+
124
+ it "does not query when touching the association" do
125
+ expect_query(0) do
126
+ expect(eager.game).to eq(game)
127
+ end
128
+ end
129
+
130
+ it "does not query when updating the association" do
131
+ expect_query(0) do
132
+ eager.game.name = "Revenge of Racing of Magic"
133
+ expect(eager.game.name).to eq("Revenge of Racing of Magic")
134
+ end
135
+ end
136
+ end
137
+
138
+ context "when the relation is polymorphic" do
139
+
140
+ let!(:book) do
141
+ Book.create(name: "Game of Thrones")
142
+ end
143
+
144
+ let!(:rating) do
145
+ book.create_rating(value: 10)
146
+ end
147
+
148
+ let!(:eager) do
149
+ Book.all.includes(:rating).first
150
+ end
151
+
152
+ it "puts the found documents in the parent document" do
153
+ expect(eager.ivar(:rating)).to eq(rating)
154
+ end
155
+
156
+ it "does not query when touching the association" do
157
+ expect_query(0) do
158
+ expect(eager.rating).to eq(rating)
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,228 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Relations::Eager do
4
+
5
+ describe ".preload" do
6
+
7
+ let(:criteria) do
8
+ Account.where(name: 'savings')
9
+ end
10
+
11
+ let(:context) do
12
+ Mongoid::Contextual::Mongo.new(criteria)
13
+ end
14
+
15
+ let(:inclusions) do
16
+ includes.map do |key|
17
+ Account.reflect_on_association(key)
18
+ end
19
+ end
20
+
21
+ let(:doc) { criteria.first }
22
+
23
+ context "when belongs_to" do
24
+
25
+ let!(:account) do
26
+ Account.create!(person: person, name: 'savings')
27
+ end
28
+
29
+ let(:person) do
30
+ Person.create!
31
+ end
32
+
33
+ let(:includes) { [:person] }
34
+
35
+ it "groups by foreign_key" do
36
+ expect(doc).to receive(:person_id).once
37
+ context.preload(inclusions, [doc])
38
+ end
39
+
40
+ it "preloads the parent" do
41
+ expect(doc.ivar(:person)).to be false
42
+ context.preload(inclusions, [doc])
43
+ expect(doc.ivar(:person)).to eq(doc.person)
44
+ end
45
+ end
46
+
47
+ context "when has_one" do
48
+
49
+ let(:account) do
50
+ Account.create!(name: 'savings')
51
+ end
52
+
53
+ let!(:comment) do
54
+ Comment.create!(title: 'my account comment', account: account)
55
+ end
56
+
57
+ let(:includes) { [:comment] }
58
+
59
+ it "preloads the child" do
60
+ expect(doc.ivar(:comment)).to be false
61
+ context.preload(inclusions, [doc])
62
+ expect(doc.ivar(:comment)).to eq(doc.comment)
63
+ end
64
+ end
65
+
66
+ context "when has_many" do
67
+
68
+ let(:account) do
69
+ Account.create!(name: 'savings')
70
+ end
71
+
72
+ let!(:alert) do
73
+ Alert.create!(account: account)
74
+ end
75
+
76
+ let(:includes) { [:alerts] }
77
+
78
+ it "preloads the child" do
79
+ expect(doc.ivar(:alerts)).to be false
80
+ context.preload(inclusions, [doc])
81
+ expect(doc.ivar(:alerts)).to eq(doc.alerts)
82
+ end
83
+ end
84
+
85
+ context "when has_and_belongs_to_many" do
86
+
87
+ let(:account) do
88
+ Account.create!(name: 'savings')
89
+ end
90
+
91
+ let!(:agent) do
92
+ Agent.create!(accounts: [account])
93
+ end
94
+
95
+ let(:includes) { [:agents] }
96
+
97
+ it "preloads the child" do
98
+ expect(doc.ivar(:agents)).to be false
99
+ context.preload(inclusions, [doc])
100
+ expect(doc.ivar(:agents)).to eq(doc.agents)
101
+ end
102
+ end
103
+ end
104
+
105
+ describe ".eager_load" do
106
+
107
+ before do
108
+ Person.create!
109
+ end
110
+
111
+ let(:context) do
112
+ Mongoid::Contextual::Mongo.new(criteria)
113
+ end
114
+
115
+ context "when including one has_many relation" do
116
+
117
+ let(:criteria) do
118
+ Person.includes(:posts)
119
+ end
120
+
121
+ let(:docs) do
122
+ Person.all.to_a
123
+ end
124
+
125
+ let(:posts_metadata) do
126
+ Person.reflect_on_association(:posts)
127
+ end
128
+
129
+ it "runs the has_many preload" do
130
+ expect(Mongoid::Relations::Eager::HasMany).to receive(:new).with([posts_metadata], docs).once.and_call_original
131
+
132
+ context.eager_load(docs)
133
+ end
134
+ end
135
+
136
+ context "when including multiple relations" do
137
+
138
+ let(:criteria) do
139
+ Person.includes(:posts, :houses, :cat)
140
+ end
141
+
142
+ let(:docs) do
143
+ Person.all.to_a
144
+ end
145
+
146
+ let(:posts_metadata) do
147
+ Person.reflect_on_association(:posts)
148
+ end
149
+
150
+ let(:houses_metadata) do
151
+ Person.reflect_on_association(:houses)
152
+ end
153
+
154
+ let(:cat_metadata) do
155
+ Person.reflect_on_association(:cat)
156
+ end
157
+
158
+ it "runs the has_many preload" do
159
+ expect(Mongoid::Relations::Eager::HasMany).to receive(:new).with([posts_metadata], docs).once.and_call_original
160
+
161
+ context.eager_load(docs)
162
+ end
163
+
164
+ it "runs the has_one preload" do
165
+ expect(Mongoid::Relations::Eager::HasOne).to receive(:new).with([cat_metadata], docs).once.and_call_original
166
+ context.eager_load(docs)
167
+ end
168
+
169
+ it "runs the has_and_belongs_to_many preload" do
170
+ expect(Mongoid::Relations::Eager::HasAndBelongsToMany).to receive(:new).with([houses_metadata], docs).once.and_call_original
171
+ context.eager_load(docs)
172
+ end
173
+ end
174
+
175
+ context "when including two of the same relation type" do
176
+
177
+ let(:criteria) do
178
+ Person.includes(:book, :cat)
179
+ end
180
+
181
+ let(:docs) do
182
+ Person.all.to_a
183
+ end
184
+
185
+ let(:book_metadata) do
186
+ Person.reflect_on_association(:book)
187
+ end
188
+
189
+ let(:cat_metadata) do
190
+ Person.reflect_on_association(:cat)
191
+ end
192
+
193
+ it "runs the has_one preload" do
194
+ expect(Mongoid::Relations::Eager::HasOne).to receive(:new).with([book_metadata, cat_metadata], docs).once.and_call_original
195
+ context.eager_load(docs)
196
+ end
197
+ end
198
+ end
199
+
200
+ describe ".eager_loadable?" do
201
+
202
+ let(:context) do
203
+ Mongoid::Contextual::Mongo.new(criteria)
204
+ end
205
+
206
+ context "when criteria has multiple includes" do
207
+
208
+ let(:criteria) do
209
+ Post.includes(:person, :roles)
210
+ end
211
+
212
+ it "is eager_loadable" do
213
+ expect(context.eager_loadable?).to be true
214
+ end
215
+ end
216
+
217
+ context "when criteria has no includes" do
218
+
219
+ let(:criteria) do
220
+ Post.all
221
+ end
222
+
223
+ it "is not eager_loadable" do
224
+ expect(context.eager_loadable?).to be false
225
+ end
226
+ end
227
+ end
228
+ end