mongoid 3.1.7 → 4.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 (567) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +470 -9
  3. data/README.md +10 -7
  4. data/lib/config/locales/en.yml +34 -20
  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 +3 -14
  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 -99
  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/memory.rb +2 -2
  19. data/lib/mongoid/contextual/aggregable/mongo.rb +5 -9
  20. data/lib/mongoid/contextual/atomic.rb +53 -53
  21. data/lib/mongoid/contextual/geo_near.rb +1 -1
  22. data/lib/mongoid/contextual/map_reduce.rb +4 -2
  23. data/lib/mongoid/contextual/memory.rb +23 -11
  24. data/lib/mongoid/contextual/mongo.rb +75 -57
  25. data/lib/mongoid/contextual/none.rb +90 -0
  26. data/lib/mongoid/contextual/text_search.rb +178 -0
  27. data/lib/mongoid/contextual.rb +2 -0
  28. data/lib/mongoid/copyable.rb +2 -3
  29. data/lib/mongoid/{criterion → criteria}/findable.rb +7 -47
  30. data/lib/mongoid/{criterion/inspection.rb → criteria/inspectable.rb} +2 -2
  31. data/lib/mongoid/{criterion → criteria}/marshalable.rb +3 -1
  32. data/lib/mongoid/{criterion → criteria}/modifiable.rb +28 -8
  33. data/lib/mongoid/criteria/permission.rb +70 -0
  34. data/lib/mongoid/{criterion/scoping.rb → criteria/scopable.rb} +2 -2
  35. data/lib/mongoid/criteria.rb +39 -34
  36. data/lib/mongoid/document.rb +39 -24
  37. data/lib/mongoid/errors/document_not_destroyed.rb +25 -0
  38. data/lib/mongoid/errors/document_not_found.rb +2 -1
  39. data/lib/mongoid/errors/invalid_storage_options.rb +1 -1
  40. data/lib/mongoid/errors/invalid_storage_parent.rb +26 -0
  41. data/lib/mongoid/errors/invalid_value.rb +16 -0
  42. data/lib/mongoid/errors/mongoid_error.rb +1 -1
  43. data/lib/mongoid/errors/readonly_document.rb +24 -0
  44. data/lib/mongoid/errors.rb +4 -1
  45. data/lib/mongoid/extensions/array.rb +3 -3
  46. data/lib/mongoid/extensions/big_decimal.rb +1 -1
  47. data/lib/mongoid/extensions/boolean.rb +15 -17
  48. data/lib/mongoid/extensions/date.rb +1 -1
  49. data/lib/mongoid/extensions/date_time.rb +3 -3
  50. data/lib/mongoid/extensions/float.rb +2 -1
  51. data/lib/mongoid/extensions/hash.rb +3 -3
  52. data/lib/mongoid/extensions/integer.rb +1 -1
  53. data/lib/mongoid/extensions/object.rb +7 -7
  54. data/lib/mongoid/extensions/object_id.rb +5 -5
  55. data/lib/mongoid/extensions/range.rb +9 -3
  56. data/lib/mongoid/extensions/regexp.rb +1 -1
  57. data/lib/mongoid/extensions/set.rb +1 -1
  58. data/lib/mongoid/extensions/string.rb +6 -18
  59. data/lib/mongoid/extensions/symbol.rb +1 -1
  60. data/lib/mongoid/extensions/time.rb +3 -3
  61. data/lib/mongoid/extensions/time_with_zone.rb +1 -1
  62. data/lib/mongoid/extensions.rb +15 -7
  63. data/lib/mongoid/factory.rb +8 -6
  64. data/lib/mongoid/fields/foreign_key.rb +3 -3
  65. data/lib/mongoid/fields/localized.rb +1 -1
  66. data/lib/mongoid/fields/standard.rb +5 -17
  67. data/lib/mongoid/fields/validators/macro.rb +15 -5
  68. data/lib/mongoid/fields.rb +41 -8
  69. data/lib/mongoid/{finders.rb → findable.rb} +35 -7
  70. data/lib/mongoid/indexable/specification.rb +104 -0
  71. data/lib/mongoid/{indexes → indexable}/validators/options.rb +2 -1
  72. data/lib/mongoid/{indexes.rb → indexable.rb} +50 -55
  73. data/lib/mongoid/{inspection.rb → inspectable.rb} +15 -11
  74. data/lib/mongoid/{callbacks.rb → interceptable.rb} +30 -62
  75. data/lib/mongoid/log_subscriber.rb +55 -0
  76. data/lib/mongoid/{matchers → matchable}/all.rb +1 -1
  77. data/lib/mongoid/{matchers → matchable}/and.rb +2 -2
  78. data/lib/mongoid/{matchers → matchable}/default.rb +1 -1
  79. data/lib/mongoid/{matchers → matchable}/exists.rb +1 -1
  80. data/lib/mongoid/{matchers → matchable}/gt.rb +1 -1
  81. data/lib/mongoid/{matchers → matchable}/gte.rb +1 -1
  82. data/lib/mongoid/{matchers → matchable}/in.rb +2 -2
  83. data/lib/mongoid/{matchers → matchable}/lt.rb +1 -1
  84. data/lib/mongoid/{matchers → matchable}/lte.rb +1 -1
  85. data/lib/mongoid/{matchers → matchable}/ne.rb +1 -1
  86. data/lib/mongoid/{matchers → matchable}/nin.rb +3 -2
  87. data/lib/mongoid/{matchers → matchable}/or.rb +2 -2
  88. data/lib/mongoid/{matchers → matchable}/size.rb +1 -1
  89. data/lib/mongoid/matchable.rb +152 -0
  90. data/lib/mongoid/persistable/creatable.rb +189 -0
  91. data/lib/mongoid/persistable/deletable.rb +149 -0
  92. data/lib/mongoid/persistable/destroyable.rb +60 -0
  93. data/lib/mongoid/persistable/incrementable.rb +36 -0
  94. data/lib/mongoid/persistable/logical.rb +38 -0
  95. data/lib/mongoid/persistable/poppable.rb +39 -0
  96. data/lib/mongoid/persistable/pullable.rb +55 -0
  97. data/lib/mongoid/persistable/pushable.rb +62 -0
  98. data/lib/mongoid/persistable/renamable.rb +35 -0
  99. data/lib/mongoid/persistable/savable.rb +52 -0
  100. data/lib/mongoid/persistable/settable.rb +33 -0
  101. data/lib/mongoid/persistable/unsettable.rb +36 -0
  102. data/lib/mongoid/persistable/updatable.rb +153 -0
  103. data/lib/mongoid/persistable/upsertable.rb +55 -0
  104. data/lib/mongoid/persistable.rb +216 -0
  105. data/lib/mongoid/positional.rb +71 -0
  106. data/lib/mongoid/query_cache.rb +255 -0
  107. data/lib/mongoid/railtie.rb +34 -60
  108. data/lib/mongoid/railties/database.rake +9 -25
  109. data/lib/mongoid/relations/accessors.rb +15 -51
  110. data/lib/mongoid/relations/auto_save.rb +15 -36
  111. data/lib/mongoid/relations/binding.rb +2 -25
  112. data/lib/mongoid/relations/bindings/embedded/in.rb +1 -1
  113. data/lib/mongoid/relations/bindings/embedded/many.rb +1 -3
  114. data/lib/mongoid/relations/bindings/referenced/in.rb +3 -8
  115. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +4 -2
  116. data/lib/mongoid/relations/builder.rb +1 -1
  117. data/lib/mongoid/relations/builders/embedded/one.rb +1 -1
  118. data/lib/mongoid/relations/builders/nested_attributes/many.rb +10 -13
  119. data/lib/mongoid/relations/builders/nested_attributes/one.rb +5 -6
  120. data/lib/mongoid/relations/builders/referenced/in.rb +1 -1
  121. data/lib/mongoid/relations/builders/referenced/many.rb +1 -2
  122. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +1 -2
  123. data/lib/mongoid/relations/builders/referenced/one.rb +1 -1
  124. data/lib/mongoid/relations/builders.rb +2 -2
  125. data/lib/mongoid/relations/cascading.rb +3 -5
  126. data/lib/mongoid/relations/constraint.rb +1 -1
  127. data/lib/mongoid/relations/conversions.rb +1 -1
  128. data/lib/mongoid/relations/counter_cache.rb +39 -15
  129. data/lib/mongoid/relations/eager/base.rb +149 -0
  130. data/lib/mongoid/relations/eager/belongs_to.rb +31 -0
  131. data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +47 -0
  132. data/lib/mongoid/relations/eager/has_many.rb +38 -0
  133. data/lib/mongoid/relations/eager/has_one.rb +30 -0
  134. data/lib/mongoid/relations/eager.rb +46 -0
  135. data/lib/mongoid/relations/embedded/batchable.rb +4 -5
  136. data/lib/mongoid/relations/embedded/in.rb +4 -4
  137. data/lib/mongoid/relations/embedded/many.rb +14 -32
  138. data/lib/mongoid/relations/embedded/one.rb +1 -1
  139. data/lib/mongoid/relations/macros.rb +3 -4
  140. data/lib/mongoid/relations/many.rb +51 -31
  141. data/lib/mongoid/relations/marshalable.rb +3 -3
  142. data/lib/mongoid/relations/metadata.rb +14 -79
  143. data/lib/mongoid/relations/nested_builder.rb +2 -2
  144. data/lib/mongoid/relations/one.rb +1 -1
  145. data/lib/mongoid/relations/options.rb +1 -0
  146. data/lib/mongoid/relations/polymorphic.rb +0 -1
  147. data/lib/mongoid/relations/proxy.rb +21 -41
  148. data/lib/mongoid/relations/referenced/in.rb +4 -20
  149. data/lib/mongoid/relations/referenced/many.rb +22 -35
  150. data/lib/mongoid/relations/referenced/many_to_many.rb +19 -42
  151. data/lib/mongoid/relations/referenced/one.rb +6 -25
  152. data/lib/mongoid/relations/synchronization.rb +4 -4
  153. data/lib/mongoid/relations/targets/enumerable.rb +10 -10
  154. data/lib/mongoid/relations/touchable.rb +34 -1
  155. data/lib/mongoid/relations.rb +11 -25
  156. data/lib/mongoid/{reloading.rb → reloadable.rb} +7 -5
  157. data/lib/mongoid/{scoping.rb → scopable.rb} +36 -36
  158. data/lib/mongoid/selectable.rb +59 -0
  159. data/lib/mongoid/{serialization.rb → serializable.rb} +11 -2
  160. data/lib/mongoid/sessions/factory.rb +2 -0
  161. data/lib/mongoid/sessions/options.rb +185 -0
  162. data/lib/mongoid/sessions/storage_options.rb +140 -0
  163. data/lib/mongoid/sessions/thread_options.rb +19 -0
  164. data/lib/mongoid/sessions/validators/storage.rb +16 -3
  165. data/lib/mongoid/sessions.rb +37 -345
  166. data/lib/mongoid/{sharding.rb → shardable.rb} +5 -1
  167. data/lib/mongoid/{state.rb → stateful.rb} +13 -1
  168. data/lib/mongoid/support/query_counter.rb +23 -0
  169. data/lib/mongoid/tasks/database.rake +31 -0
  170. data/lib/mongoid/tasks/database.rb +107 -0
  171. data/lib/mongoid/threaded/lifecycle.rb +0 -28
  172. data/lib/mongoid/threaded.rb +26 -172
  173. data/lib/mongoid/timestamps/updated/short.rb +2 -2
  174. data/lib/mongoid/{hierarchy.rb → traversable.rb} +15 -7
  175. data/lib/mongoid/{validations → validatable}/associated.rb +4 -2
  176. data/lib/mongoid/{validations → validatable}/format.rb +1 -1
  177. data/lib/mongoid/{validations → validatable}/length.rb +1 -1
  178. data/lib/mongoid/{validations → validatable}/localizable.rb +1 -1
  179. data/lib/mongoid/{validations → validatable}/macros.rb +4 -3
  180. data/lib/mongoid/{validations → validatable}/presence.rb +1 -1
  181. data/lib/mongoid/{validations → validatable}/queryable.rb +1 -2
  182. data/lib/mongoid/{validations → validatable}/uniqueness.rb +25 -21
  183. data/lib/mongoid/{validations.rb → validatable.rb} +23 -10
  184. data/lib/mongoid/version.rb +1 -1
  185. data/lib/mongoid.rb +10 -76
  186. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +46 -25
  187. data/lib/rails/generators/mongoid/model/model_generator.rb +0 -1
  188. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +0 -3
  189. data/lib/rails/generators/mongoid_generator.rb +3 -40
  190. data/lib/rails/mongoid.rb +0 -122
  191. data/lib/support/ruby_version.rb +1 -1
  192. data/spec/app/models/account.rb +2 -6
  193. data/spec/app/models/acolyte.rb +2 -1
  194. data/spec/app/models/actor.rb +0 -1
  195. data/spec/app/models/address.rb +8 -3
  196. data/spec/app/models/animal.rb +1 -1
  197. data/spec/app/models/appointment.rb +3 -3
  198. data/spec/app/models/article.rb +1 -4
  199. data/spec/app/models/audio.rb +5 -0
  200. data/spec/app/models/author.rb +0 -2
  201. data/spec/app/models/band.rb +3 -2
  202. data/spec/app/models/bar.rb +1 -0
  203. data/spec/app/models/book.rb +1 -0
  204. data/spec/app/models/building.rb +0 -2
  205. data/spec/app/models/building_address.rb +0 -2
  206. data/spec/app/models/bus.rb +1 -1
  207. data/spec/app/models/canvas.rb +1 -1
  208. data/spec/app/models/contextable_item.rb +5 -0
  209. data/spec/app/models/contractor.rb +0 -2
  210. data/spec/app/models/country_code.rb +1 -1
  211. data/spec/app/models/definition.rb +2 -2
  212. data/spec/app/models/dog.rb +1 -1
  213. data/spec/app/models/dragon.rb +4 -0
  214. data/spec/app/models/drug.rb +1 -3
  215. data/spec/app/models/dungeon.rb +4 -0
  216. data/spec/app/models/edit.rb +5 -0
  217. data/spec/app/models/even.rb +7 -0
  218. data/spec/app/models/event.rb +1 -1
  219. data/spec/app/models/filesystem.rb +1 -0
  220. data/spec/app/models/fish.rb +0 -1
  221. data/spec/app/models/fruits.rb +6 -0
  222. data/spec/app/models/game.rb +0 -2
  223. data/spec/app/models/house.rb +1 -3
  224. data/spec/app/models/id_key.rb +6 -0
  225. data/spec/app/models/item.rb +1 -5
  226. data/spec/app/models/jar.rb +1 -1
  227. data/spec/app/models/label.rb +4 -4
  228. data/spec/app/models/line_item.rb +1 -1
  229. data/spec/app/models/login.rb +1 -1
  230. data/spec/app/models/message.rb +8 -0
  231. data/spec/app/models/movie.rb +1 -0
  232. data/spec/app/models/name.rb +3 -3
  233. data/spec/app/models/note.rb +3 -1
  234. data/spec/app/models/odd.rb +7 -0
  235. data/spec/app/models/oscar.rb +1 -1
  236. data/spec/app/models/parent_doc.rb +1 -1
  237. data/spec/app/models/person.rb +16 -10
  238. data/spec/app/models/phone.rb +1 -3
  239. data/spec/app/models/player.rb +3 -3
  240. data/spec/app/models/post.rb +5 -3
  241. data/spec/app/models/preference.rb +1 -1
  242. data/spec/app/models/quiz.rb +0 -3
  243. data/spec/app/models/record.rb +10 -5
  244. data/spec/app/models/registry.rb +1 -1
  245. data/spec/app/models/server.rb +1 -1
  246. data/spec/app/models/service.rb +3 -3
  247. data/spec/app/models/sound.rb +5 -0
  248. data/spec/app/models/symptom.rb +1 -1
  249. data/spec/app/models/template.rb +1 -1
  250. data/spec/app/models/title.rb +0 -1
  251. data/spec/app/models/track.rb +5 -5
  252. data/spec/app/models/tree.rb +3 -3
  253. data/spec/app/models/video.rb +1 -5
  254. data/spec/app/models/wiki_page.rb +2 -5
  255. data/spec/app/models/word.rb +3 -0
  256. data/spec/app/models/word_origin.rb +1 -1
  257. data/spec/config/mongoid.yml +7 -8
  258. data/spec/helpers.rb +18 -0
  259. data/spec/mongoid/atomic/modifiers_spec.rb +22 -22
  260. data/spec/mongoid/atomic/paths/embedded/many_spec.rb +8 -49
  261. data/spec/mongoid/atomic/paths/embedded/one_spec.rb +7 -49
  262. data/spec/mongoid/atomic/paths/root_spec.rb +3 -61
  263. data/spec/mongoid/atomic/paths_spec.rb +19 -19
  264. data/spec/mongoid/atomic_spec.rb +19 -19
  265. data/spec/mongoid/{nested_attributes_spec.rb → attributes/nested_spec.rb} +474 -592
  266. data/spec/mongoid/attributes/readonly_spec.rb +58 -18
  267. data/spec/mongoid/attributes_spec.rb +334 -434
  268. data/spec/mongoid/{dirty_spec.rb → changeable_spec.rb} +203 -153
  269. data/spec/mongoid/{components_spec.rb → composable_spec.rb} +3 -3
  270. data/spec/mongoid/config/environment_spec.rb +3 -3
  271. data/spec/mongoid/config/options_spec.rb +6 -6
  272. data/spec/mongoid/config_spec.rb +24 -48
  273. data/spec/mongoid/contextual/aggregable/memory_spec.rb +12 -12
  274. data/spec/mongoid/contextual/aggregable/mongo_spec.rb +46 -38
  275. data/spec/mongoid/contextual/atomic_spec.rb +59 -55
  276. data/spec/mongoid/contextual/find_and_modify_spec.rb +14 -14
  277. data/spec/mongoid/contextual/geo_near_spec.rb +22 -22
  278. data/spec/mongoid/contextual/map_reduce_spec.rb +27 -27
  279. data/spec/mongoid/contextual/memory_spec.rb +156 -94
  280. data/spec/mongoid/contextual/mongo_spec.rb +238 -150
  281. data/spec/mongoid/contextual/none_spec.rb +127 -0
  282. data/spec/mongoid/contextual/text_search_spec.rb +209 -0
  283. data/spec/mongoid/copyable_spec.rb +56 -68
  284. data/spec/mongoid/criteria/findable_spec.rb +991 -0
  285. data/spec/mongoid/{criterion/inspection_spec.rb → criteria/inspectable_spec.rb} +5 -5
  286. data/spec/mongoid/{criterion → criteria}/marshalable_spec.rb +2 -2
  287. data/spec/mongoid/criteria/modifiable_spec.rb +1252 -0
  288. data/spec/mongoid/{criterion/scoping_spec.rb → criteria/scopable_spec.rb} +37 -37
  289. data/spec/mongoid/criteria_spec.rb +713 -2419
  290. data/spec/mongoid/document_spec.rb +171 -121
  291. data/spec/mongoid/equality_spec.rb +22 -22
  292. data/spec/mongoid/errors/ambiguous_relationship_spec.rb +3 -3
  293. data/spec/mongoid/errors/callback_spec.rb +3 -3
  294. data/spec/mongoid/errors/delete_restriction_spec.rb +3 -3
  295. data/spec/mongoid/errors/document_not_destroyed_spec.rb +33 -0
  296. data/spec/mongoid/errors/document_not_found_spec.rb +11 -11
  297. data/spec/mongoid/errors/eager_load_spec.rb +3 -3
  298. data/spec/mongoid/errors/invalid_collection_spec.rb +3 -3
  299. data/spec/mongoid/errors/invalid_config_option_spec.rb +3 -3
  300. data/spec/mongoid/errors/invalid_field_option_spec.rb +3 -3
  301. data/spec/mongoid/errors/invalid_field_spec.rb +3 -3
  302. data/spec/mongoid/errors/invalid_find_spec.rb +3 -3
  303. data/spec/mongoid/errors/invalid_includes_spec.rb +3 -3
  304. data/spec/mongoid/errors/invalid_index_spec.rb +3 -3
  305. data/spec/mongoid/errors/invalid_options_spec.rb +3 -3
  306. data/spec/mongoid/errors/invalid_path_spec.rb +3 -3
  307. data/spec/mongoid/errors/invalid_scope_spec.rb +5 -5
  308. data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +3 -3
  309. data/spec/mongoid/errors/invalid_storage_options_spec.rb +3 -3
  310. data/spec/mongoid/errors/invalid_time_spec.rb +3 -3
  311. data/spec/mongoid/errors/inverse_not_found_spec.rb +3 -3
  312. data/spec/mongoid/errors/mixed_relations_spec.rb +3 -3
  313. data/spec/mongoid/errors/mixed_session_configuration_spec.rb +3 -3
  314. data/spec/mongoid/errors/mongoid_error_spec.rb +8 -8
  315. data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +3 -3
  316. data/spec/mongoid/errors/no_environment_spec.rb +3 -3
  317. data/spec/mongoid/errors/no_map_reduce_output_spec.rb +3 -3
  318. data/spec/mongoid/errors/no_metadata_spec.rb +3 -3
  319. data/spec/mongoid/errors/no_parent_spec.rb +3 -3
  320. data/spec/mongoid/errors/no_session_config_spec.rb +3 -3
  321. data/spec/mongoid/errors/no_session_database_spec.rb +3 -3
  322. data/spec/mongoid/errors/no_session_hosts_spec.rb +3 -3
  323. data/spec/mongoid/errors/no_sessions_config_spec.rb +3 -3
  324. data/spec/mongoid/errors/readonly_attribute_spec.rb +3 -3
  325. data/spec/mongoid/errors/readonly_document_spec.rb +29 -0
  326. data/spec/mongoid/errors/scope_overwrite_spec.rb +3 -3
  327. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +3 -3
  328. data/spec/mongoid/errors/unknown_attribute_spec.rb +5 -5
  329. data/spec/mongoid/errors/unsaved_document_spec.rb +3 -3
  330. data/spec/mongoid/errors/unsupported_javascript_spec.rb +3 -3
  331. data/spec/mongoid/errors/validations_spec.rb +7 -7
  332. data/spec/mongoid/extensions/array_spec.rb +61 -61
  333. data/spec/mongoid/extensions/big_decimal_spec.rb +11 -11
  334. data/spec/mongoid/extensions/binary_spec.rb +12 -12
  335. data/spec/mongoid/extensions/boolean_spec.rb +18 -18
  336. data/spec/mongoid/extensions/date_spec.rb +13 -13
  337. data/spec/mongoid/extensions/date_time_spec.rb +8 -8
  338. data/spec/mongoid/extensions/false_class_spec.rb +5 -5
  339. data/spec/mongoid/extensions/float_spec.rb +29 -15
  340. data/spec/mongoid/extensions/hash_spec.rb +29 -29
  341. data/spec/mongoid/extensions/integer_spec.rb +15 -15
  342. data/spec/mongoid/extensions/module_spec.rb +2 -2
  343. data/spec/mongoid/extensions/nil_class_spec.rb +1 -1
  344. data/spec/mongoid/extensions/object_id_spec.rb +134 -134
  345. data/spec/mongoid/extensions/object_spec.rb +26 -26
  346. data/spec/mongoid/extensions/range_spec.rb +61 -12
  347. data/spec/mongoid/extensions/regexp_spec.rb +4 -4
  348. data/spec/mongoid/extensions/set_spec.rb +4 -4
  349. data/spec/mongoid/extensions/string_spec.rb +35 -46
  350. data/spec/mongoid/extensions/symbol_spec.rb +9 -9
  351. data/spec/mongoid/extensions/time_spec.rb +49 -49
  352. data/spec/mongoid/extensions/time_with_zone_spec.rb +34 -34
  353. data/spec/mongoid/extensions/true_class_spec.rb +5 -5
  354. data/spec/mongoid/extensions_spec.rb +29 -0
  355. data/spec/mongoid/factory_spec.rb +15 -15
  356. data/spec/mongoid/fields/foreign_key_spec.rb +73 -66
  357. data/spec/mongoid/fields/internal/foreign_keys/array_spec.rb +15 -15
  358. data/spec/mongoid/fields/internal/foreign_keys/object_spec.rb +22 -22
  359. data/spec/mongoid/fields/localized_spec.rb +38 -23
  360. data/spec/mongoid/fields/standard_spec.rb +12 -12
  361. data/spec/mongoid/fields_spec.rb +263 -217
  362. data/spec/mongoid/findable_spec.rb +509 -0
  363. data/spec/mongoid/indexable/specification_spec.rb +102 -0
  364. data/spec/mongoid/{indexes_spec.rb → indexable_spec.rb} +171 -51
  365. data/spec/mongoid/{inspection_spec.rb → inspectable_spec.rb} +6 -14
  366. data/spec/mongoid/{callbacks_spec.rb → interceptable_spec.rb} +117 -116
  367. data/spec/mongoid/log_subscriber_spec.rb +75 -0
  368. data/spec/mongoid/loggable_spec.rb +1 -1
  369. data/spec/mongoid/{matchers → matchable}/all_spec.rb +4 -4
  370. data/spec/mongoid/{matchers → matchable}/and_spec.rb +11 -11
  371. data/spec/mongoid/{matchers → matchable}/default_spec.rb +15 -15
  372. data/spec/mongoid/{matchers → matchable}/exists_spec.rb +5 -5
  373. data/spec/mongoid/{matchers → matchable}/gt_spec.rb +9 -8
  374. data/spec/mongoid/{matchers → matchable}/gte_spec.rb +7 -7
  375. data/spec/mongoid/matchable/in_spec.rb +49 -0
  376. data/spec/mongoid/{matchers → matchable}/lt_spec.rb +7 -7
  377. data/spec/mongoid/{matchers → matchable}/lte_spec.rb +7 -7
  378. data/spec/mongoid/{matchers → matchable}/ne_spec.rb +3 -3
  379. data/spec/mongoid/matchable/nin_spec.rb +48 -0
  380. data/spec/mongoid/{matchers → matchable}/or_spec.rb +6 -6
  381. data/spec/mongoid/{matchers → matchable}/size_spec.rb +3 -3
  382. data/spec/mongoid/{matchers_spec.rb → matchable_spec.rb} +41 -41
  383. data/spec/mongoid/persistable/creatable_spec.rb +553 -0
  384. data/spec/mongoid/persistable/deletable_spec.rb +218 -0
  385. data/spec/mongoid/persistable/destroyable_spec.rb +192 -0
  386. data/spec/mongoid/persistable/incrementable_spec.rb +173 -0
  387. data/spec/mongoid/persistable/logical_spec.rb +143 -0
  388. data/spec/mongoid/persistable/poppable_spec.rb +115 -0
  389. data/spec/mongoid/persistable/pullable_spec.rb +228 -0
  390. data/spec/mongoid/persistable/pushable_spec.rb +258 -0
  391. data/spec/mongoid/persistable/renamable_spec.rb +135 -0
  392. data/spec/mongoid/persistable/savable_spec.rb +498 -0
  393. data/spec/mongoid/persistable/settable_spec.rb +162 -0
  394. data/spec/mongoid/persistable/unsettable_spec.rb +155 -0
  395. data/spec/mongoid/persistable/updatable_spec.rb +558 -0
  396. data/spec/mongoid/persistable/upsertable_spec.rb +106 -0
  397. data/spec/mongoid/persistable_spec.rb +206 -0
  398. data/spec/mongoid/{atomic/positionable_spec.rb → positional_spec.rb} +9 -9
  399. data/spec/mongoid/query_cache_spec.rb +263 -0
  400. data/spec/mongoid/railties/document_spec.rb +2 -2
  401. data/spec/mongoid/relations/accessors_spec.rb +53 -145
  402. data/spec/mongoid/relations/auto_save_spec.rb +37 -17
  403. data/spec/mongoid/relations/bindings/embedded/in_spec.rb +12 -12
  404. data/spec/mongoid/relations/bindings/embedded/many_spec.rb +3 -3
  405. data/spec/mongoid/relations/bindings/embedded/one_spec.rb +5 -5
  406. data/spec/mongoid/relations/bindings/referenced/in_spec.rb +26 -26
  407. data/spec/mongoid/relations/bindings/referenced/many_spec.rb +10 -10
  408. data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +19 -19
  409. data/spec/mongoid/relations/bindings/referenced/one_spec.rb +12 -12
  410. data/spec/mongoid/relations/builders/embedded/in_spec.rb +4 -4
  411. data/spec/mongoid/relations/builders/embedded/many_spec.rb +18 -18
  412. data/spec/mongoid/relations/builders/embedded/one_spec.rb +11 -11
  413. data/spec/mongoid/relations/builders/nested_attributes/many_spec.rb +12 -13
  414. data/spec/mongoid/relations/builders/nested_attributes/one_spec.rb +14 -14
  415. data/spec/mongoid/relations/builders/referenced/in_spec.rb +24 -35
  416. data/spec/mongoid/relations/builders/referenced/many_spec.rb +15 -15
  417. data/spec/mongoid/relations/builders/referenced/many_to_many_spec.rb +18 -18
  418. data/spec/mongoid/relations/builders/referenced/one_spec.rb +12 -25
  419. data/spec/mongoid/relations/builders_spec.rb +21 -21
  420. data/spec/mongoid/relations/cascading/delete_spec.rb +9 -9
  421. data/spec/mongoid/relations/cascading/destroy_spec.rb +6 -6
  422. data/spec/mongoid/relations/cascading/nullify_spec.rb +4 -4
  423. data/spec/mongoid/relations/cascading/restrict_spec.rb +7 -7
  424. data/spec/mongoid/relations/cascading_spec.rb +16 -16
  425. data/spec/mongoid/relations/constraint_spec.rb +8 -7
  426. data/spec/mongoid/relations/conversions_spec.rb +16 -14
  427. data/spec/mongoid/relations/counter_cache_spec.rb +85 -0
  428. data/spec/mongoid/relations/cyclic_spec.rb +18 -18
  429. data/spec/mongoid/relations/eager/belongs_to_spec.rb +154 -0
  430. data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +117 -0
  431. data/spec/mongoid/relations/eager/has_many_spec.rb +207 -0
  432. data/spec/mongoid/relations/eager/has_one_spec.rb +163 -0
  433. data/spec/mongoid/relations/eager_spec.rb +228 -0
  434. data/spec/mongoid/relations/embedded/dirty_spec.rb +8 -8
  435. data/spec/mongoid/relations/embedded/in_spec.rb +56 -57
  436. data/spec/mongoid/relations/embedded/many_spec.rb +467 -372
  437. data/spec/mongoid/relations/embedded/one_spec.rb +108 -141
  438. data/spec/mongoid/relations/macros_spec.rb +108 -102
  439. data/spec/mongoid/relations/metadata_spec.rb +180 -255
  440. data/spec/mongoid/relations/options_spec.rb +1 -1
  441. data/spec/mongoid/relations/polymorphic_spec.rb +13 -17
  442. data/spec/mongoid/relations/proxy_spec.rb +2 -2
  443. data/spec/mongoid/relations/referenced/in_spec.rb +128 -303
  444. data/spec/mongoid/relations/referenced/many_spec.rb +587 -527
  445. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +401 -424
  446. data/spec/mongoid/relations/referenced/one_spec.rb +149 -264
  447. data/spec/mongoid/relations/reflections_spec.rb +6 -6
  448. data/spec/mongoid/relations/synchronization_spec.rb +46 -50
  449. data/spec/mongoid/relations/targets/enumerable_spec.rb +118 -118
  450. data/spec/mongoid/relations/touchable_spec.rb +333 -0
  451. data/spec/mongoid/relations_spec.rb +16 -15
  452. data/spec/mongoid/{reloading_spec.rb → reloadable_spec.rb} +38 -55
  453. data/spec/mongoid/{scoping_spec.rb → scopable_spec.rb} +89 -164
  454. data/spec/mongoid/selectable_spec.rb +134 -0
  455. data/spec/mongoid/{serialization_spec.rb → serializable_spec.rb} +129 -82
  456. data/spec/mongoid/sessions/factory_spec.rb +49 -28
  457. data/spec/mongoid/sessions/mongo_uri_spec.rb +7 -7
  458. data/spec/mongoid/sessions/options_spec.rb +108 -0
  459. data/spec/mongoid/sessions_spec.rb +319 -178
  460. data/spec/mongoid/{sharding_spec.rb → shardable_spec.rb} +8 -8
  461. data/spec/mongoid/{state_spec.rb → stateful_spec.rb} +36 -11
  462. data/spec/mongoid/tasks/database_rake_spec.rb +285 -0
  463. data/spec/mongoid/tasks/database_spec.rb +160 -0
  464. data/spec/mongoid/threaded_spec.rb +17 -70
  465. data/spec/mongoid/timestamps/created/short_spec.rb +6 -6
  466. data/spec/mongoid/timestamps/created_spec.rb +5 -5
  467. data/spec/mongoid/timestamps/timeless_spec.rb +6 -6
  468. data/spec/mongoid/timestamps/updated/short_spec.rb +11 -11
  469. data/spec/mongoid/timestamps/updated_spec.rb +9 -13
  470. data/spec/mongoid/timestamps_spec.rb +9 -13
  471. data/spec/mongoid/{hierarchy_spec.rb → traversable_spec.rb} +19 -19
  472. data/spec/mongoid/{validations → validatable}/associated_spec.rb +45 -22
  473. data/spec/mongoid/{validations → validatable}/format_spec.rb +6 -6
  474. data/spec/mongoid/{validations → validatable}/length_spec.rb +14 -14
  475. data/spec/mongoid/{validations → validatable}/numericality_spec.rb +1 -1
  476. data/spec/mongoid/{validations → validatable}/presence_spec.rb +37 -44
  477. data/spec/mongoid/{validations → validatable}/uniqueness_spec.rb +184 -192
  478. data/spec/mongoid/{validations_spec.rb → validatable_spec.rb} +28 -28
  479. data/spec/mongoid_spec.rb +8 -8
  480. data/spec/rails/mongoid_spec.rb +19 -350
  481. data/spec/spec_helper.rb +26 -15
  482. metadata +262 -247
  483. data/lib/mongoid/atomic/positionable.rb +0 -73
  484. data/lib/mongoid/components.rb +0 -92
  485. data/lib/mongoid/config/inflections.rb +0 -6
  486. data/lib/mongoid/contextual/eager.rb +0 -158
  487. data/lib/mongoid/errors/versioning_not_on_root.rb +0 -23
  488. data/lib/mongoid/identity_map.rb +0 -163
  489. data/lib/mongoid/json.rb +0 -16
  490. data/lib/mongoid/matchers/strategies.rb +0 -97
  491. data/lib/mongoid/matchers.rb +0 -32
  492. data/lib/mongoid/multi_parameter_attributes.rb +0 -105
  493. data/lib/mongoid/nested_attributes.rb +0 -78
  494. data/lib/mongoid/observer.rb +0 -192
  495. data/lib/mongoid/paranoia.rb +0 -136
  496. data/lib/mongoid/persistence/atomic/add_to_set.rb +0 -47
  497. data/lib/mongoid/persistence/atomic/bit.rb +0 -35
  498. data/lib/mongoid/persistence/atomic/inc.rb +0 -45
  499. data/lib/mongoid/persistence/atomic/operation.rb +0 -154
  500. data/lib/mongoid/persistence/atomic/pop.rb +0 -32
  501. data/lib/mongoid/persistence/atomic/pull.rb +0 -32
  502. data/lib/mongoid/persistence/atomic/pull_all.rb +0 -32
  503. data/lib/mongoid/persistence/atomic/push.rb +0 -25
  504. data/lib/mongoid/persistence/atomic/push_all.rb +0 -25
  505. data/lib/mongoid/persistence/atomic/rename.rb +0 -30
  506. data/lib/mongoid/persistence/atomic/sets.rb +0 -28
  507. data/lib/mongoid/persistence/atomic/unset.rb +0 -27
  508. data/lib/mongoid/persistence/atomic.rb +0 -231
  509. data/lib/mongoid/persistence/deletion.rb +0 -31
  510. data/lib/mongoid/persistence/insertion.rb +0 -38
  511. data/lib/mongoid/persistence/modification.rb +0 -35
  512. data/lib/mongoid/persistence/operations/embedded/insert.rb +0 -46
  513. data/lib/mongoid/persistence/operations/embedded/remove.rb +0 -43
  514. data/lib/mongoid/persistence/operations/insert.rb +0 -34
  515. data/lib/mongoid/persistence/operations/remove.rb +0 -33
  516. data/lib/mongoid/persistence/operations/update.rb +0 -59
  517. data/lib/mongoid/persistence/operations/upsert.rb +0 -28
  518. data/lib/mongoid/persistence/operations.rb +0 -214
  519. data/lib/mongoid/persistence/upsertion.rb +0 -31
  520. data/lib/mongoid/persistence.rb +0 -357
  521. data/lib/mongoid/unit_of_work.rb +0 -61
  522. data/lib/mongoid/versioning.rb +0 -217
  523. data/lib/rack/mongoid/middleware/identity_map.rb +0 -39
  524. data/lib/rack/mongoid.rb +0 -2
  525. data/lib/rails/generators/mongoid/observer/observer_generator.rb +0 -17
  526. data/lib/rails/generators/mongoid/observer/templates/observer.rb.tt +0 -4
  527. data/spec/app/models/actor_observer.rb +0 -15
  528. data/spec/app/models/callback_recorder.rb +0 -25
  529. data/spec/app/models/paranoid_phone.rb +0 -25
  530. data/spec/app/models/paranoid_post.rb +0 -36
  531. data/spec/app/models/phone_observer.rb +0 -6
  532. data/spec/mongoid/attributes/processing_spec.rb +0 -149
  533. data/spec/mongoid/criterion/destructive_spec.rb +0 -101
  534. data/spec/mongoid/criterion/modifiable_spec.rb +0 -409
  535. data/spec/mongoid/criterion/modification_spec.rb +0 -402
  536. data/spec/mongoid/errors/versioning_not_on_root_spec.rb +0 -29
  537. data/spec/mongoid/finders_spec.rb +0 -321
  538. data/spec/mongoid/identity_map_spec.rb +0 -564
  539. data/spec/mongoid/json_spec.rb +0 -33
  540. data/spec/mongoid/matchers/in_spec.rb +0 -25
  541. data/spec/mongoid/matchers/nin_spec.rb +0 -25
  542. data/spec/mongoid/multi_parameter_attributes_spec.rb +0 -128
  543. data/spec/mongoid/observer_spec.rb +0 -290
  544. data/spec/mongoid/paranoia_spec.rb +0 -759
  545. data/spec/mongoid/persistence/atomic/add_to_set_spec.rb +0 -262
  546. data/spec/mongoid/persistence/atomic/bit_spec.rb +0 -88
  547. data/spec/mongoid/persistence/atomic/inc_spec.rb +0 -133
  548. data/spec/mongoid/persistence/atomic/pop_spec.rb +0 -111
  549. data/spec/mongoid/persistence/atomic/pull_all_spec.rb +0 -77
  550. data/spec/mongoid/persistence/atomic/pull_spec.rb +0 -80
  551. data/spec/mongoid/persistence/atomic/push_all_spec.rb +0 -77
  552. data/spec/mongoid/persistence/atomic/push_spec.rb +0 -77
  553. data/spec/mongoid/persistence/atomic/rename_spec.rb +0 -42
  554. data/spec/mongoid/persistence/atomic/sets_spec.rb +0 -154
  555. data/spec/mongoid/persistence/atomic/unset_spec.rb +0 -65
  556. data/spec/mongoid/persistence/atomic_spec.rb +0 -216
  557. data/spec/mongoid/persistence/operations/embedded/insert_spec.rb +0 -191
  558. data/spec/mongoid/persistence/operations/embedded/remove_spec.rb +0 -8
  559. data/spec/mongoid/persistence/operations/insert_spec.rb +0 -149
  560. data/spec/mongoid/persistence/operations/remove_spec.rb +0 -113
  561. data/spec/mongoid/persistence/operations/update_spec.rb +0 -141
  562. data/spec/mongoid/persistence/operations/upsert_spec.rb +0 -59
  563. data/spec/mongoid/persistence/operations_spec.rb +0 -313
  564. data/spec/mongoid/persistence_spec.rb +0 -2279
  565. data/spec/mongoid/unit_of_work_spec.rb +0 -196
  566. data/spec/mongoid/versioning_spec.rb +0 -540
  567. data/spec/rack/mongoid/middleware/identity_map_spec.rb +0 -72
@@ -6,84 +6,76 @@ module Mongoid
6
6
  # Execute an atomic $addToSet on the matching documents.
7
7
  #
8
8
  # @example Add the value to the set.
9
- # context.add_to_set(:members, "Dave")
9
+ # context.add_to_set(members: "Dave", genres: "Electro")
10
10
  #
11
- # @param [ String, Symbol ] field The name of the field to add to.
12
- # @param [ Object ] value The single value to add.
11
+ # @param [ Hash ] adds The operations.
13
12
  #
14
13
  # @return [ nil ] Nil.
15
14
  #
16
15
  # @since 3.0.0
17
- def add_to_set(field, value)
18
- query.update_all("$addToSet" => { database_field_name(field) => value })
16
+ def add_to_set(adds)
17
+ query.update_all("$addToSet" => collect_operations(adds))
19
18
  end
20
19
 
21
20
  # Perform an atomic $bit operation on the matching documents.
22
21
  #
23
22
  # @example Perform the bitwise op.
24
- # context.bit(:likes, { and: 14, or: 4 })
23
+ # context.bit(likes: { and: 14, or: 4 })
25
24
  #
26
- # @param [ String, Symbol ] field The name of the field to operate on.
27
- # @param [ Hash ] value The bitwise operations to perform. Keys may be
28
- # "and" or "or" and must have numeric values.
25
+ # @param [ Hash ] bits The operations.
29
26
  #
30
27
  # @return [ nil ] Nil.
31
28
  #
32
29
  # @since 3.0.0
33
- def bit(field, value)
34
- query.update_all("$bit" => { database_field_name(field) => value })
30
+ def bit(bits)
31
+ query.update_all("$bit" => collect_operations(bits))
35
32
  end
36
33
 
37
34
  # Perform an atomic $inc operation on the matching documents.
38
35
  #
39
36
  # @example Perform the atomic increment.
40
- # context.inc(:likes, 10)
37
+ # context.inc(likes: 10)
41
38
  #
42
- # @param [ String, Symbol ] field The field to increment.
43
- # @param [ Integer ] value The amount to increment by.
39
+ # @param [ Hash ] incs The operations.
44
40
  #
45
41
  # @return [ nil ] Nil.
46
42
  #
47
43
  # @since 3.0.0
48
- def inc(field, value)
49
- query.update_all("$inc" => { database_field_name(field) => value })
44
+ def inc(incs)
45
+ query.update_all("$inc" => collect_operations(incs))
50
46
  end
51
47
 
52
48
  # Perform an atomic $pop operation on the matching documents.
53
49
  #
54
50
  # @example Pop the first value on the matches.
55
- # context.pop(:members, -1)
51
+ # context.pop(members: -1)
56
52
  #
57
53
  # @example Pop the last value on the matches.
58
- # context.pop(:members, 1)
54
+ # context.pop(members: 1)
59
55
  #
60
- # @param [ String, Symbol ] field The name of the array field to pop
61
- # from.
62
- # @param [ Integer ] value 1 to pop from the end, -1 to pop from the
63
- # front.
56
+ # @param [ Hash ] pops The operations.
64
57
  #
65
58
  # @return [ nil ] Nil.
66
59
  #
67
60
  # @since 3.0.0
68
- def pop(field, value)
69
- query.update_all("$pop" => { database_field_name(field) => value })
61
+ def pop(pops)
62
+ query.update_all("$pop" => collect_operations(pops))
70
63
  end
71
64
 
72
65
  # Perform an atomic $pull operation on the matching documents.
73
66
  #
74
67
  # @example Pull the value from the matches.
75
- # context.pull(:members, "Dave")
68
+ # context.pull(members: "Dave")
76
69
  #
77
70
  # @note Expression pulling is not yet supported.
78
71
  #
79
- # @param [ String, Symbol ] field The field to pull from.
80
- # @param [ Object ] value The single value to pull.
72
+ # @param [ Hash ] pulls The operations.
81
73
  #
82
74
  # @return [ nil ] Nil.
83
75
  #
84
76
  # @since 3.0.0
85
- def pull(field, value)
86
- query.update_all("$pull" => { database_field_name(field) => value })
77
+ def pull(pulls)
78
+ query.update_all("$pull" => collect_operations(pulls))
87
79
  end
88
80
 
89
81
  # Perform an atomic $pullAll operation on the matching documents.
@@ -91,74 +83,73 @@ module Mongoid
91
83
  # @example Pull all the matching values from the matches.
92
84
  # context.pull_all(:members, [ "Alan", "Vince" ])
93
85
  #
94
- # @param [ String, Symbol ] field The field to pull from.
95
- # @param [ Array<Object> ] values The values to pull.
86
+ # @param [ Hash ] pulls The operations.
96
87
  #
97
88
  # @return [ nil ] Nil.
98
89
  #
99
90
  # @since 3.0.0
100
- def pull_all(field, values)
101
- query.update_all("$pullAll" => { database_field_name(field) => values })
91
+ def pull_all(pulls)
92
+ query.update_all("$pullAll" => collect_operations(pulls))
102
93
  end
103
94
 
104
95
  # Perform an atomic $push operation on the matching documents.
105
96
  #
106
97
  # @example Push the value to the matching docs.
107
- # context.push(:members, "Alan")
98
+ # context.push(members: "Alan")
108
99
  #
109
- # @param [ String, Symbol ] field The field to push to.
110
- # @param [ Object ] value The value to push.
100
+ # @param [ Hash ] pushes The operations.
111
101
  #
112
102
  # @return [ nil ] Nil.
113
103
  #
114
104
  # @since 3.0.0
115
- def push(field, value)
116
- query.update_all("$push" => { database_field_name(field) => value })
105
+ def push(pushes)
106
+ query.update_all("$push" => collect_operations(pushes))
117
107
  end
118
108
 
119
109
  # Perform an atomic $pushAll operation on the matching documents.
120
110
  #
121
111
  # @example Push the values to the matching docs.
122
- # context.push(:members, [ "Alan", "Fletch" ])
112
+ # context.push(members: [ "Alan", "Fletch" ])
123
113
  #
124
- # @param [ String, Symbol ] field The field to push to.
125
- # @param [ Array<Object> ] values The values to push.
114
+ # @param [ Hash ] pushes The operations.
126
115
  #
127
116
  # @return [ nil ] Nil.
128
117
  #
129
118
  # @since 3.0.0
130
- def push_all(field, values)
131
- query.update_all("$pushAll" => { database_field_name(field) => values })
119
+ def push_all(pushes)
120
+ query.update_all("$pushAll" => collect_operations(pushes))
132
121
  end
133
122
 
134
123
  # Perform an atomic $rename of fields on the matching documents.
135
124
  #
136
125
  # @example Rename the fields on the matching documents.
137
- # context.rename(:members, :artists)
126
+ # context.rename(members: :artists)
138
127
  #
139
- # @param [ String, Symbol ] old_name The old field name.
140
- # @param [ String, Symbol ] new_name The new field name.
128
+ # @param [ Hash ] renames The operations.
141
129
  #
142
130
  # @return [ nil ] Nil.
143
131
  #
144
132
  # @since 3.0.0
145
- def rename(old_name, new_name)
146
- query.update_all("$rename" => { database_field_name(old_name) => new_name.to_s })
133
+ def rename(renames)
134
+ operations = renames.inject({}) do |ops, (old_name, new_name)|
135
+ ops[old_name] = new_name.to_s
136
+ ops
137
+ end
138
+ query.update_all("$rename" => collect_operations(operations))
147
139
  end
148
140
 
149
141
  # Perform an atomic $set of fields on the matching documents.
150
142
  #
151
143
  # @example Set the field value on the matches.
152
- # context.set(:name, "Depeche Mode")
144
+ # context.set(name: "Depeche Mode")
153
145
  #
154
- # @param [ String, Symbol ] field The name of the field.
155
- # @param [ Object ] value The value to set.
146
+ # @param [ Hash ] sets The operations.
156
147
  #
157
148
  # @return [ nil ] Nil.
158
149
  #
159
150
  # @since 3.0.0
160
- def set(field, value)
161
- query.update_all("$set" => { database_field_name(field) => value })
151
+ def set(sets)
152
+ query.update_all("$set" => collect_operations(sets))
162
153
  end
163
154
 
164
155
  # Perform an atomic $unset of a field on the matching documents.
@@ -175,6 +166,15 @@ module Mongoid
175
166
  fields = args.__find_args__.collect { |f| [database_field_name(f), true] }
176
167
  query.update_all("$unset" => Hash[fields])
177
168
  end
169
+
170
+ private
171
+
172
+ def collect_operations(ops)
173
+ ops.inject({}) do |operations, (field, value)|
174
+ operations[database_field_name(field)] = value.mongoize
175
+ operations
176
+ end
177
+ end
178
178
  end
179
179
  end
180
180
  end
@@ -213,7 +213,7 @@ module Mongoid
213
213
  # @since 3.0.0
214
214
  def documents
215
215
  results["results"].map do |attributes|
216
- doc = Factory.from_db(criteria.klass, attributes["obj"], criteria.object_id)
216
+ doc = Factory.from_db(criteria.klass, attributes["obj"], criteria.options[:fields])
217
217
  doc.attributes["geo_near_distance"] = attributes["dis"]
218
218
  doc
219
219
  end
@@ -268,7 +268,9 @@ module Mongoid
268
268
  # @since 3.0.0
269
269
  def documents
270
270
  return results["results"] if results.has_key?("results")
271
- session[output_collection].find
271
+ query = session[output_collection].find
272
+ query.no_timeout if criteria.options[:timeout] == false
273
+ query
272
274
  end
273
275
 
274
276
  # Get the collection that the map/reduce results were stored in.
@@ -314,7 +316,7 @@ module Mongoid
314
316
  # @since 3.0.15
315
317
  def __session__
316
318
  if command[:out][:inline] != 1
317
- session.with(consistency: :strong)
319
+ session.with(read: :primary)
318
320
  else
319
321
  session
320
322
  end
@@ -1,14 +1,15 @@
1
1
  # encoding: utf-8
2
2
  require "mongoid/contextual/aggregable/memory"
3
+ require "mongoid/relations/eager"
3
4
 
4
5
  module Mongoid
5
6
  module Contextual
6
7
  class Memory
7
8
  include Enumerable
8
9
  include Aggregable::Memory
9
- include Eager
10
+ include Relations::Eager
10
11
  include Queryable
11
- include Mongoid::Atomic::Positionable
12
+ include Positional
12
13
 
13
14
  # @attribute [r] root The root document.
14
15
  # @attribute [r] path The atomic path.
@@ -102,7 +103,7 @@ module Mongoid
102
103
  documents_for_iteration.each do |doc|
103
104
  yield(doc)
104
105
  end
105
- # eager_loadable? ? docs : self
106
+ self
106
107
  else
107
108
  to_enum
108
109
  end
@@ -130,10 +131,11 @@ module Mongoid
130
131
  # @since 3.0.0
131
132
  def first
132
133
  doc = documents.first
133
- eager_load_one(doc) if eager_loadable?(doc)
134
+ eager_load_one(doc)
134
135
  doc
135
136
  end
136
137
  alias :one :first
138
+ alias :find_first :first
137
139
 
138
140
  # Create the new in memory context.
139
141
  #
@@ -164,7 +166,7 @@ module Mongoid
164
166
  # @since 3.0.0
165
167
  def last
166
168
  doc = documents.last
167
- eager_load_one(doc) if eager_loadable?(doc)
169
+ eager_load_one(doc)
168
170
  doc
169
171
  end
170
172
 
@@ -196,6 +198,17 @@ module Mongoid
196
198
  self
197
199
  end
198
200
 
201
+ def pluck(*fields)
202
+ fields = Array.wrap(fields)
203
+ documents.map do |doc|
204
+ if fields.size == 1
205
+ doc[fields.first]
206
+ else
207
+ fields.map { |n| doc[n] }.compact
208
+ end
209
+ end.compact
210
+ end
211
+
199
212
  # Skips the provided number of documents.
200
213
  #
201
214
  # @example Skip the documents.
@@ -294,7 +307,7 @@ module Mongoid
294
307
  updates["$set"].merge!(doc.atomic_updates["$set"] || {})
295
308
  doc.move_changes
296
309
  end
297
- collection.find(selector).update(updates)
310
+ collection.find(selector).update(updates) unless updates["$set"].empty?
298
311
  end
299
312
 
300
313
  # Get the limiting value.
@@ -409,12 +422,11 @@ module Mongoid
409
422
  #
410
423
  # @since 3.0.0
411
424
  def in_place_sort(values)
412
- values.keys.reverse.each do |field|
413
- documents.sort! do |a, b|
425
+ documents.sort! do |a, b|
426
+ values.map do |field, direction|
414
427
  a_value, b_value = a[field], b[field]
415
- value = compare(a_value.__sortable__, b_value.__sortable__)
416
- values[field] < 0 ? value * -1 : value
417
- end
428
+ direction * compare(a_value.__sortable__, b_value.__sortable__)
429
+ end.find { |value| !value.zero? } || 0
418
430
  end
419
431
  end
420
432
 
@@ -2,10 +2,11 @@
2
2
  require "mongoid/contextual/atomic"
3
3
  require "mongoid/contextual/aggregable/mongo"
4
4
  require "mongoid/contextual/command"
5
- require "mongoid/contextual/eager"
6
5
  require "mongoid/contextual/find_and_modify"
7
6
  require "mongoid/contextual/geo_near"
8
7
  require "mongoid/contextual/map_reduce"
8
+ require "mongoid/contextual/text_search"
9
+ require "mongoid/relations/eager"
9
10
 
10
11
  module Mongoid
11
12
  module Contextual
@@ -13,7 +14,7 @@ module Mongoid
13
14
  include Enumerable
14
15
  include Aggregable::Mongo
15
16
  include Atomic
16
- include Eager
17
+ include Relations::Eager
17
18
  include Queryable
18
19
 
19
20
  # @attribute [r] query The Moped query.
@@ -53,10 +54,10 @@ module Mongoid
53
54
  def count(document = false, &block)
54
55
  return super(&block) if block_given?
55
56
  if document.is_a?(Document)
56
- return collection.find(criteria.and(_id: document.id).selector).count
57
+ return collection.find(criteria.and(_id: document._id).selector).count
57
58
  end
58
59
  return query.count(document) if document
59
- cached? ? @count ||= query.count : query.count
60
+ try_cache(:count) { query.count }
60
61
  end
61
62
 
62
63
  # Delete all documents in the database that match the selector.
@@ -118,13 +119,11 @@ module Mongoid
118
119
  # @since 3.0.0
119
120
  def each(&block)
120
121
  if block_given?
121
- selecting do
122
- documents_for_iteration.each do |doc|
123
- yield_document(doc, &block)
124
- end
125
- @cache_loaded = true
126
- eager_loadable? ? docs : self
122
+ documents_for_iteration.each do |doc|
123
+ yield_document(doc, &block)
127
124
  end
125
+ @cache_loaded = true
126
+ self
128
127
  else
129
128
  to_enum
130
129
  end
@@ -143,7 +142,12 @@ module Mongoid
143
142
  #
144
143
  # @since 3.0.0
145
144
  def exists?
146
- @exists ||= check_existence
145
+ return !documents.empty? if cached? && cache_loaded?
146
+ return @count > 0 if instance_variable_defined?(:@count)
147
+
148
+ try_cache(:exists) do
149
+ !!(query.dup.select(_id: 1).limit(1).first)
150
+ end
147
151
  end
148
152
 
149
153
  # Run an explain on the criteria.
@@ -189,9 +193,8 @@ module Mongoid
189
193
  #
190
194
  # @since 3.0.0
191
195
  def first
192
- if cached? && cache_loaded?
193
- documents.first
194
- else
196
+ return documents.first if cached? && cache_loaded?
197
+ try_cache(:first) do
195
198
  with_sorting do
196
199
  with_eager_loading(query.first)
197
200
  end
@@ -199,6 +202,16 @@ module Mongoid
199
202
  end
200
203
  alias :one :first
201
204
 
205
+ # Return the first result without applying sort
206
+ #
207
+ # @api private
208
+ #
209
+ # @since 4.0.2
210
+ def find_first
211
+ return documents.first if cached? && cache_loaded?
212
+ with_eager_loading(query.first)
213
+ end
214
+
202
215
  # Execute a $geoNear command against the database.
203
216
  #
204
217
  # @example Find documents close to 10, 10.
@@ -257,7 +270,7 @@ module Mongoid
257
270
  # @since 3.0.0
258
271
  def initialize(criteria)
259
272
  @criteria, @klass, @cache = criteria, criteria.klass, criteria.options[:cache]
260
- @collection = klass.collection
273
+ @collection = @klass.with(criteria.persistence_options || {}).collection
261
274
  criteria.send(:merge_type_selection)
262
275
  @query = collection.find(criteria.selector)
263
276
  apply_options
@@ -274,8 +287,10 @@ module Mongoid
274
287
  #
275
288
  # @since 3.0.0
276
289
  def last
277
- with_inverse_sorting do
278
- with_eager_loading(query.first)
290
+ try_cache(:last) do
291
+ with_inverse_sorting do
292
+ with_eager_loading(query.first)
293
+ end
279
294
  end
280
295
  end
281
296
 
@@ -330,14 +345,24 @@ module Mongoid
330
345
  # @note This method will return the raw db values - it performs no custom
331
346
  # serialization.
332
347
  #
333
- # @param [ String, Symbol ] field The field to pluck.
348
+ # @param [ String, Symbol, Array ] field Fields to pluck.
334
349
  #
335
- # @return [ Array<Object> ] The plucked values.
350
+ # @return [ Array<Object, Array> ] The plucked values.
336
351
  #
337
352
  # @since 3.1.0
338
- def pluck(field)
339
- normalized = klass.database_field_name(field)
340
- query.dup.select(normalized => 1).map{ |doc| doc[normalized] }.compact
353
+ def pluck(*fields)
354
+ normalized_select = fields.inject({}) do |hash, f|
355
+ hash[klass.database_field_name(f)] = 1
356
+ hash
357
+ end
358
+
359
+ query.dup.select(normalized_select).map do |doc|
360
+ if normalized_select.size == 1
361
+ doc[normalized_select.keys.first]
362
+ else
363
+ normalized_select.keys.map { |n| doc[n] }
364
+ end
365
+ end
341
366
  end
342
367
 
343
368
  # Skips the provided number of documents.
@@ -376,6 +401,20 @@ module Mongoid
376
401
  end
377
402
  end
378
403
 
404
+ # Execute a text command against the database.
405
+ #
406
+ # @example Find documents with the text "phase"
407
+ # context.text_search("phase")
408
+ #
409
+ # @param [ String ] query The text search query.
410
+ #
411
+ # @return [ TextSearch ] The TextSearch command.
412
+ #
413
+ # @since 4.0.0
414
+ def text_search(query)
415
+ TextSearch.new(collection, criteria, query)
416
+ end
417
+
379
418
  # Update the first matching document atomically.
380
419
  #
381
420
  # @example Update the first matching document.
@@ -393,7 +432,7 @@ module Mongoid
393
432
  # Update all the matching documents atomically.
394
433
  #
395
434
  # @example Update all the matching documents.
396
- # context.update({ "$set" => { name: "Smiths" }})
435
+ # context.update_all({ "$set" => { name: "Smiths" }})
397
436
  #
398
437
  # @param [ Hash ] attributes The new attributes for each document.
399
438
  #
@@ -406,21 +445,21 @@ module Mongoid
406
445
 
407
446
  private
408
447
 
409
- # Checks if any documents exist in the database.
410
- #
411
- # @api private
448
+ # yield the block given or return the cached value
412
449
  #
413
- # @example Check for document existsence.
414
- # context.check_existence
450
+ # @param [ String, Symbol ] key The instance variable name
415
451
  #
416
- # @return [ true, false ] If documents exist.
452
+ # @return the result of the block
417
453
  #
418
- # @since 3.1.0
419
- def check_existence
420
- if cached? && cache_loaded?
421
- !documents.empty?
454
+ # @since 3.1.4
455
+ def try_cache(key, &block)
456
+ unless cached?
457
+ yield
422
458
  else
423
- @count ? @count > 0 : !query.dup.select(_id: 1).limit(1).entries.first.nil?
459
+ unless ret = instance_variable_get("@#{key}")
460
+ instance_variable_set("@#{key}", ret = yield)
461
+ end
462
+ ret
424
463
  end
425
464
  end
426
465
 
@@ -593,7 +632,7 @@ module Mongoid
593
632
  if cached? && !documents.empty?
594
633
  documents
595
634
  elsif eager_loadable?
596
- docs = query.map{ |doc| Factory.from_db(klass, doc) }
635
+ docs = query.map{ |doc| Factory.from_db(klass, doc, criteria.options[:fields]) }
597
636
  eager_load(docs)
598
637
  docs
599
638
  else
@@ -601,27 +640,6 @@ module Mongoid
601
640
  end
602
641
  end
603
642
 
604
- # If we are limiting results, we need to set the field limitations on a
605
- # thread local to avoid overriding the default values.
606
- #
607
- # @example Execute with selection.
608
- # context.selecting do
609
- # collection.find
610
- # end
611
- #
612
- # @return [ Object ] The yielded value.
613
- #
614
- # @since 2.4.4
615
- def selecting
616
- begin
617
- fields = criteria.options[:fields]
618
- Threaded.set_selection(criteria.object_id, fields) unless fields.blank?
619
- yield
620
- ensure
621
- Threaded.delete_selection(criteria.object_id)
622
- end
623
- end
624
-
625
643
  # Yield to the document.
626
644
  #
627
645
  # @api private
@@ -636,7 +654,7 @@ module Mongoid
636
654
  # @since 3.0.0
637
655
  def yield_document(document, &block)
638
656
  doc = document.respond_to?(:_id) ?
639
- document : Factory.from_db(klass, document, criteria.object_id)
657
+ document : Factory.from_db(klass, document, criteria.options[:fields])
640
658
  yield(doc)
641
659
  documents.push(doc) if cacheable?
642
660
  end
@@ -0,0 +1,90 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module Contextual
4
+ class None
5
+ include Enumerable
6
+ include Queryable
7
+
8
+ attr_reader :criteria, :klass
9
+
10
+ # Check if the context is equal to the other object.
11
+ #
12
+ # @example Check equality.
13
+ # context == []
14
+ #
15
+ # @param [ Array ] other The other array.
16
+ #
17
+ # @return [ true, false ] If the objects are equal.
18
+ #
19
+ # @since 4.0.0
20
+ def ==(other)
21
+ other.is_a?(None)
22
+ end
23
+
24
+ # Iterate over the null context. There are no documents to iterate over
25
+ # in this case.
26
+ #
27
+ # @example Iterate over the context.
28
+ # context.each do |doc|
29
+ # puts doc.name
30
+ # end
31
+ #
32
+ # @return [ Enumerator ] The enumerator.
33
+ #
34
+ # @since 4.0.0
35
+ def each
36
+ if block_given?
37
+ [].each { |doc| yield(doc) }
38
+ self
39
+ else
40
+ to_enum
41
+ end
42
+ end
43
+
44
+ # Do any documents exist for the context.
45
+ #
46
+ # @example Do any documents exist for the context.
47
+ # context.exists?
48
+ #
49
+ # @return [ true, false ] If the count is more than zero.
50
+ #
51
+ # @since 4.0.0
52
+ def exists?; false; end
53
+
54
+ # Create the new null context.
55
+ #
56
+ # @example Create the new context.
57
+ # Null.new(criteria)
58
+ #
59
+ # @param [ Criteria ] The criteria.
60
+ #
61
+ # @since 4.0.0
62
+ def initialize(criteria)
63
+ @criteria, @klass = criteria, criteria.klass
64
+ end
65
+
66
+ # Always returns nil.
67
+ #
68
+ # @example Get the last document.
69
+ # context.last
70
+ #
71
+ # @return [ nil ] Always nil.
72
+ #
73
+ # @since 4.0.0
74
+ def last; nil; end
75
+
76
+ # Always returns zero.
77
+ #
78
+ # @example Get the length of matching documents.
79
+ # context.length
80
+ #
81
+ # @return [ Integer ] Always zero.
82
+ #
83
+ # @since 4.0.0
84
+ def length
85
+ entries.length
86
+ end
87
+ alias :size :length
88
+ end
89
+ end
90
+ end