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
@@ -0,0 +1,71 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+
4
+ # This module is responsible for taking update selectors and switching out
5
+ # the indexes for the $ positional operator where appropriate.
6
+ #
7
+ # @since 4.0.0
8
+ module Positional
9
+
10
+ # Takes the provided selector and atomic operations and replaces the
11
+ # indexes of the embedded documents with the positional operator when
12
+ # needed.
13
+ #
14
+ # @note The only time we can accurately know when to use the positional
15
+ # operator is at the exact time we are going to persist something. So
16
+ # we can tell by the selector that we are sending if it is actually
17
+ # possible to use the positional operator at all. For example, if the
18
+ # selector is: { "_id" => 1 }, then we could not use the positional
19
+ # operator for updating embedded documents since there would never be a
20
+ # match - we base whether we can based on the number of levels deep the
21
+ # selector goes, and if the id values are not nil.
22
+ #
23
+ # @example Process the operations.
24
+ # positionally(
25
+ # { "_id" => 1, "addresses._id" => 2 },
26
+ # { "$set" => { "addresses.0.street" => "hobrecht" }}
27
+ # )
28
+ #
29
+ # @param [ Hash ] selector The selector.
30
+ # @param [ Hash ] operations The update operations.
31
+ # @param [ Hash ] processed The processed update operations.
32
+ #
33
+ # @return [ Hash ] The new operations.
34
+ #
35
+ # @since 3.1.0
36
+ def positionally(selector, operations, processed = {})
37
+ if selector.size == 1 || selector.values.any? { |val| val.nil? }
38
+ return operations
39
+ end
40
+ keys = selector.keys.map{ |m| m.sub('._id','') } - ['_id']
41
+ keys = keys.sort_by { |s| s.length*-1 }
42
+ process_operations(keys, operations, processed)
43
+ end
44
+
45
+ private
46
+
47
+ def process_operations(keys, operations, processed)
48
+ operations.each_pair do |operation, update|
49
+ processed[operation] = process_updates(keys, update)
50
+ end
51
+ processed
52
+ end
53
+
54
+ def process_updates(keys, update, updates = {})
55
+ update.each_pair do |position, value|
56
+ updates[replace_index(keys, position)] = value
57
+ end
58
+ updates
59
+ end
60
+
61
+ def replace_index(keys, position)
62
+ # replace to $ only if that key is on the selector
63
+ keys.each do |kk|
64
+ if position =~ /^#{kk}\.\d+\.(.*)/
65
+ return "#{kk}.$.#{$1}"
66
+ end
67
+ end
68
+ position
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,255 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+
4
+ # A cache of database queries on a per-request basis.
5
+ #
6
+ # @since 4.0.0
7
+ module QueryCache
8
+ class << self
9
+
10
+ # Get the cached queries.
11
+ #
12
+ # @example Get the cached queries from the current thread.
13
+ # QueryCache.cache_table
14
+ #
15
+ # @return [ Hash ] The hash of cached queries.
16
+ #
17
+ # @since 4.0.0
18
+ def cache_table
19
+ Thread.current["[mongoid]:query_cache"] ||= {}
20
+ end
21
+
22
+ # Clear the query cache.
23
+ #
24
+ # @example Clear the cache.
25
+ # QueryCache.clear_cache
26
+ #
27
+ # @return [ nil ] Always nil.
28
+ #
29
+ # @since 4.0.0
30
+ def clear_cache
31
+ Thread.current["[mongoid]:query_cache"] = nil
32
+ end
33
+
34
+ # Set whether the cache is enabled.
35
+ #
36
+ # @example Set if the cache is enabled.
37
+ # QueryCache.enabled = true
38
+ #
39
+ # @param [ true, false ] value The enabled value.
40
+ #
41
+ # @since 4.0.0
42
+ def enabled=(value)
43
+ Thread.current["[mongoid]:query_cache:enabled"] = value
44
+ end
45
+
46
+ # Is the query cache enabled on the current thread?
47
+ #
48
+ # @example Is the query cache enabled?
49
+ # QueryCache.enabled?
50
+ #
51
+ # @return [ true, false ] If the cache is enabled.
52
+ #
53
+ # @since 4.0.0
54
+ def enabled?
55
+ !!Thread.current["[mongoid]:query_cache:enabled"]
56
+ end
57
+
58
+ # Execute the block while using the query cache.
59
+ #
60
+ # @example Execute with the cache.
61
+ # QueryCache.cache { collection.find }
62
+ #
63
+ # @return [ Object ] The result of the block.
64
+ #
65
+ # @since 4.0.0
66
+ def cache
67
+ enabled = QueryCache.enabled?
68
+ QueryCache.enabled = true
69
+ yield
70
+ ensure
71
+ QueryCache.enabled = enabled
72
+ end
73
+ end
74
+
75
+ # The middleware to be added to a rack application in order to activate the
76
+ # query cache.
77
+ #
78
+ # @since 4.0.0
79
+ class Middleware
80
+
81
+ # Instantiate the middleware.
82
+ #
83
+ # @example Create the new middleware.
84
+ # Middleware.new(app)
85
+ #
86
+ # @param [ Object ] app The rack applciation stack.
87
+ #
88
+ # @since 4.0.0
89
+ def initialize(app)
90
+ @app = app
91
+ end
92
+
93
+ # Execute the request, wrapping in a query cache.
94
+ #
95
+ # @example Execute the request.
96
+ # middleware.call(env)
97
+ #
98
+ # @param [ Object ] env The environment.
99
+ #
100
+ # @return [ Object ] The result of the call.
101
+ #
102
+ # @since 4.0.0
103
+ def call(env)
104
+ QueryCache.cache { @app.call(env) }
105
+ ensure
106
+ QueryCache.clear_cache
107
+ end
108
+ end
109
+
110
+ module Base # :nodoc:
111
+
112
+ def alias_query_cache_clear(*method_names)
113
+ method_names.each do |method_name|
114
+ class_eval <<-CODE, __FILE__, __LINE__ + 1
115
+ def #{method_name}_with_clear_cache(*args) # def upsert_with_clear_cache(*args)
116
+ QueryCache.clear_cache # QueryCache.clear_cache
117
+ #{method_name}_without_clear_cache(*args) # upsert_without_clear_cache(*args)
118
+ end # end
119
+ CODE
120
+
121
+ alias_method_chain method_name, :clear_cache
122
+ end
123
+ end
124
+ end
125
+
126
+ # Module to include in objects which need to wrap caching behaviour around
127
+ # them.
128
+ #
129
+ # @since 4.0.0
130
+ module Cacheable
131
+
132
+ private
133
+
134
+ def with_cache(context = :cursor, more = false, &block)
135
+ return yield unless QueryCache.enabled?
136
+ return yield if system_collection?
137
+ key = cache_key.push(context)
138
+
139
+ if more
140
+ docs = yield
141
+ QueryCache.cache_table[key].push(*docs)
142
+ docs
143
+ elsif QueryCache.cache_table.has_key?(key)
144
+ instrument(key) { QueryCache.cache_table[key] }
145
+ else
146
+ QueryCache.cache_table[key] = yield
147
+ end
148
+ end
149
+
150
+ def instrument(key, &block)
151
+ ActiveSupport::Notifications.instrument("query_cache.mongoid", key: key, &block)
152
+ end
153
+ end
154
+
155
+ # Adds behaviour around caching to a Moped Query object.
156
+ #
157
+ # @since 4.0.0
158
+ module Query
159
+ extend ActiveSupport::Concern
160
+ include Cacheable
161
+
162
+ included do
163
+ extend QueryCache::Base
164
+ alias_method_chain :cursor, :cache
165
+ alias_method_chain :first, :cache
166
+ alias_query_cache_clear :remove, :remove_all, :update, :update_all, :upsert
167
+ end
168
+
169
+ # Provide a wrapped query cache cursor.
170
+ #
171
+ # @example Get the wrapped caching cursor.
172
+ # query.cursor_with_cache
173
+ #
174
+ # @return [ CachedCursor ] The cached cursor.
175
+ #
176
+ # @since 4.0.0
177
+ def cursor_with_cache
178
+ CachedCursor.new(session, operation)
179
+ end
180
+
181
+ # Override first with caching.
182
+ #
183
+ # @example Get the first with a cache.
184
+ # query.first_with_cache
185
+ #
186
+ # @return [ Hash ] The first document.
187
+ #
188
+ # @since 4.0.0
189
+ def first_with_cache
190
+ with_cache(:first) do
191
+ first_without_cache
192
+ end
193
+ end
194
+
195
+ private
196
+
197
+ def cache_key
198
+ [ operation.database, operation.collection, operation.selector, operation.limit, operation.skip, operation.fields ]
199
+ end
200
+
201
+ def system_collection?
202
+ operation.collection =~ /^system./
203
+ end
204
+ end
205
+
206
+ # Adds behaviour to the query cache for collections.
207
+ #
208
+ # @since 4.0.0
209
+ module Collection
210
+ extend ActiveSupport::Concern
211
+
212
+ included do
213
+ extend QueryCache::Base
214
+ alias_query_cache_clear :insert
215
+ end
216
+ end
217
+
218
+ # A Cursor that attempts to load documents from memory first before hitting
219
+ # the database if the same query has already been executed.
220
+ #
221
+ # @since 4.0.0
222
+ class CachedCursor < Moped::Cursor
223
+ include Cacheable
224
+
225
+ # Override the loading of docs to attempt to fetch from the cache.
226
+ #
227
+ # @example Load the documents.
228
+ # cursor.load_docs
229
+ #
230
+ # @return [ Array<Hash> ] The documents.
231
+ #
232
+ # @since 4.0.0
233
+ def load_docs
234
+ with_cache { super }
235
+ end
236
+
237
+ def get_more
238
+ with_cache(:cursor, true) { super }
239
+ end
240
+
241
+ private
242
+
243
+ def cache_key
244
+ [ @database, @collection, @selector, @options[:limit], @options[:skip], @options[:fields] ]
245
+ end
246
+
247
+ def system_collection?
248
+ @collection =~ /^system./
249
+ end
250
+ end
251
+ end
252
+ end
253
+
254
+ Moped::Query.__send__(:include, Mongoid::QueryCache::Query)
255
+ Moped::Collection.__send__(:include, Mongoid::QueryCache::Collection)
@@ -7,20 +7,11 @@ require "rails/mongoid"
7
7
 
8
8
  module Rails
9
9
  module Mongoid
10
- class Railtie < Rails::Railtie
11
10
 
12
- # Determine which generator to use. app_generators was introduced after
13
- # 3.0.0.
14
- #
15
- # @example Get the generators method.
16
- # railtie.generators
17
- #
18
- # @return [ Symbol ] The method name to use.
19
- #
20
- # @since 2.0.0.rc.4
21
- def self.generator
22
- config.respond_to?(:app_generators) ? :app_generators : :generators
23
- end
11
+ # Hooks Mongoid into Rails 3 and higher.
12
+ #
13
+ # @since 2.0.0
14
+ class Railtie < Rails::Railtie
24
15
 
25
16
  # Mapping of rescued exceptions to HTTP responses
26
17
  #
@@ -37,7 +28,7 @@ module Rails
37
28
  }
38
29
  end
39
30
 
40
- config.send(generator).orm :mongoid, migration: false
31
+ config.app_generators.orm :mongoid, migration: false
41
32
 
42
33
  if config.action_dispatch.rescue_responses
43
34
  config.action_dispatch.rescue_responses.merge!(rescue_responses)
@@ -56,11 +47,15 @@ module Rails
56
47
  # config.mongoid.persist_in_safe_mode = true
57
48
  # end
58
49
  # end
50
+ #
51
+ # @since 2.0.0
59
52
  config.mongoid = ::Mongoid::Config
60
53
 
61
54
  # Initialize Mongoid. This will look for a mongoid.yml in the config
62
55
  # directory and configure mongoid appropriately.
63
- initializer "setup database" do
56
+ #
57
+ # @since 2.0.0
58
+ initializer "mongoid.load-config" do
64
59
  config_file = Rails.root.join("config", "mongoid.yml")
65
60
  if config_file.file?
66
61
  begin
@@ -79,64 +74,41 @@ module Rails
79
74
 
80
75
  # Set the proper error types for Rails. DocumentNotFound errors should be
81
76
  # 404s and not 500s, validation errors are 422s.
82
- initializer "load http errors" do |app|
83
- config.after_initialize do
84
- unless config.action_dispatch.rescue_responses
85
- ActionDispatch::ShowExceptions.rescue_responses.update(Railtie.rescue_responses)
86
- end
77
+ #
78
+ # @since 2.0.0
79
+ config.after_initialize do
80
+ unless config.action_dispatch.rescue_responses
81
+ ActionDispatch::ShowExceptions.rescue_responses.update(Railtie.rescue_responses)
87
82
  end
88
83
  end
89
84
 
90
85
  # Due to all models not getting loaded and messing up inheritance queries
91
86
  # and indexing, we need to preload the models in order to address this.
92
87
  #
93
- # This will happen every request in development, once in ther other
88
+ # This will happen for every request in development, once in other
94
89
  # environments.
95
- initializer "preload all application models" do |app|
90
+ #
91
+ # @since 2.0.0
92
+ initializer "mongoid.preload-models" do |app|
96
93
  config.to_prepare do
97
- if $rails_rake_task
98
- # We previously got rid of this, however in the case where
99
- # threadsafe! is enabled we must load all models so things like
100
- # creating indexes works properly.
101
- ::Rails::Mongoid.load_models(app)
102
- else
103
- ::Rails::Mongoid.preload_models(app)
104
- end
94
+ ::Rails::Mongoid.preload_models(app)
105
95
  end
106
96
  end
107
97
 
108
- # Need to include the Mongoid identity map middleware.
109
- initializer "include the identity map" do |app|
110
- app.config.middleware.use "Rack::Mongoid::Middleware::IdentityMap"
111
- end
112
-
113
- # Instantitate any registered observers after Rails initialization and
114
- # instantiate them after being reloaded in the development environment
115
- initializer "instantiate observers" do
116
- config.after_initialize do
117
- ::Mongoid::instantiate_observers
118
- ActionDispatch::Reloader.to_prepare do
119
- ::Mongoid.instantiate_observers
120
- end
98
+ config.after_initialize do
99
+ # Unicorn clears the START_CTX when a worker is forked, so if we have
100
+ # data in START_CTX then we know we're being preloaded. Unicorn does
101
+ # not provide application-level hooks for executing code after the
102
+ # process has forked, so we reconnect lazily.
103
+ if defined?(Unicorn) && !Unicorn::HttpServer::START_CTX.empty?
104
+ ::Mongoid.default_session.disconnect if ::Mongoid.configured?
121
105
  end
122
- end
123
-
124
- initializer "reconnect to master if application is preloaded" do
125
- config.after_initialize do
126
- # Unicorn clears the START_CTX when a worker is forked, so if we have
127
- # data in START_CTX then we know we're being preloaded. Unicorn does
128
- # not provide application-level hooks for executing code after the
129
- # process has forked, so we reconnect lazily.
130
- if defined?(Unicorn) && !Unicorn::HttpServer::START_CTX.empty?
131
- ::Mongoid.default_session.disconnect if ::Mongoid.configured?
132
- end
133
106
 
134
- # Passenger provides the :starting_worker_process event for executing
135
- # code after it has forked, so we use that and reconnect immediately.
136
- if ::Mongoid.running_with_passenger?
137
- PhusionPassenger.on_event(:starting_worker_process) do |forked|
138
- ::Mongoid.default_session.disconnect if forked
139
- end
107
+ # Passenger provides the :starting_worker_process event for executing
108
+ # code after it has forked, so we use that and reconnect immediately.
109
+ if ::Mongoid::Config.running_with_passenger?
110
+ PhusionPassenger.on_event(:starting_worker_process) do |forked|
111
+ ::Mongoid.default_session.disconnect if forked
140
112
  end
141
113
  end
142
114
  end
@@ -145,6 +117,8 @@ module Rails
145
117
  # code, so we have no way in the intitializer to know if we are
146
118
  # generating a mongoid.yml. So instead of failing, we catch all the
147
119
  # errors and print them out.
120
+ #
121
+ # @since 3.0.0
148
122
  def handle_configuration_error(e)
149
123
  puts "There is a configuration error with the current mongoid.yml."
150
124
  puts e.message
@@ -1,3 +1,5 @@
1
+ load 'mongoid/tasks/database.rake'
2
+
1
3
  namespace :db do
2
4
 
3
5
  unless Rake::Task.task_defined?("db:drop")
@@ -21,12 +23,12 @@ namespace :db do
21
23
 
22
24
  unless Rake::Task.task_defined?("db:setup")
23
25
  desc "Create the database, and initialize with the seed data"
24
- task :setup => [ "db:create", "db:mongoid:create_indexes", "db:seed" ]
26
+ task :setup => [ "db:create", "mongoid:create_indexes", "db:seed" ]
25
27
  end
26
28
 
27
- unless Rake::Task.task_defined?("db:reseed")
28
- desc "Delete data and seed"
29
- task :reseed => [ "db:drop", "db:seed" ]
29
+ unless Rake::Task.task_defined?("db:reset")
30
+ desc "Delete data and loads the seeds"
31
+ task :reset => [ "db:drop", "db:seed" ]
30
32
  end
31
33
 
32
34
  unless Rake::Task.task_defined?("db:create")
@@ -51,9 +53,7 @@ namespace :db do
51
53
 
52
54
  unless Rake::Task.task_defined?("db:test:prepare")
53
55
  namespace :test do
54
- task :prepare do
55
- # noop
56
- end
56
+ task :prepare => "mongoid:create_indexes"
57
57
  end
58
58
  end
59
59
 
@@ -66,24 +66,8 @@ namespace :db do
66
66
  end
67
67
 
68
68
  namespace :mongoid do
69
- desc "Create the indexes defined on your mongoid models"
70
- task :create_indexes => :environment do
71
- ::Rails::Mongoid.create_indexes
72
- end
73
-
74
- desc "Remove the indexes defined on your mongoid models without questions!"
75
- task :remove_indexes => :environment do
76
- ::Rails::Mongoid.remove_indexes
77
- end
78
-
79
- desc "Drops the database for the current Rails.env"
80
- task :drop => :environment do
81
- ::Mongoid::Sessions.default.drop
82
- end
83
-
84
- desc "Drop all collections except the system collections"
85
- task :purge => :environment do
86
- ::Mongoid.purge!
69
+ task :load_models do
70
+ ::Rails.application.eager_load! if defined?(Rails)
87
71
  end
88
72
  end
89
73
  end
@@ -12,10 +12,10 @@ module Mongoid
12
12
  # document is nil, then sets the relation on this document.
13
13
  #
14
14
  # @example Build the relation.
15
- # person.__build__(:addresses, { :id => 1 }, metadata)
15
+ # person.__build__(:addresses, { :_id => 1 }, metadata)
16
16
  #
17
17
  # @param [ String, Symbol ] name The name of the relation.
18
- # @param [ Hash, Moped::BSON::ObjectId ] object The id or attributes to use.
18
+ # @param [ Hash, BSON::ObjectId ] object The id or attributes to use.
19
19
  # @param [ Metadata ] metadata The relation's metadata.
20
20
  # @param [ true, false ] building If we are in a build operation.
21
21
  #
@@ -44,20 +44,6 @@ module Mongoid
44
44
  target ? metadata.relation.new(self, target, metadata) : nil
45
45
  end
46
46
 
47
- # Determines if the relation exists or not.
48
- #
49
- # @example Does the relation exist?
50
- # person.relation_exists?(:people)
51
- #
52
- # @param [ String ] name The name of the relation to check.
53
- #
54
- # @return [ true, false ] True if set and not nil, false if not.
55
- #
56
- # @since 2.0.0.rc.1
57
- def relation_exists?(name)
58
- ivar(name)
59
- end
60
-
61
47
  # Resets the criteria inside the relation proxy. Used by many to many
62
48
  # relations to keep the underlying ids array in sync.
63
49
  #
@@ -68,7 +54,7 @@ module Mongoid
68
54
  #
69
55
  # @since 3.0.14
70
56
  def reset_relation_criteria(name)
71
- if instance_variable_defined?("@#{name}")
57
+ if instance_variable_defined?("@_#{name}")
72
58
  send(name).reset_unloaded
73
59
  end
74
60
  end
@@ -86,7 +72,7 @@ module Mongoid
86
72
  #
87
73
  # @since 2.0.0.rc.1
88
74
  def set_relation(name, relation)
89
- instance_variable_set("@#{name}", relation)
75
+ instance_variable_set("@_#{name}", relation)
90
76
  end
91
77
 
92
78
  private
@@ -106,34 +92,13 @@ module Mongoid
106
92
  # @return [ Proxy ] The relation.
107
93
  #
108
94
  # @since 3.0.16
109
- def get_relation(name, metadata, reload = false)
110
- variable = "@#{name}"
111
- value = if instance_variable_defined?(variable) && !reload
112
- instance_variable_get(variable)
113
- else
114
- _building do
115
- _loading do
116
- __build__(name, attributes[metadata.key], metadata)
117
- end
118
- end
119
- end
120
- if value.nil? && metadata.autobuilding? && !without_autobuild?
121
- send("build_#{name}")
122
- else
95
+ def get_relation(name, metadata, object, reload = false)
96
+ if !reload && (value = ivar(name)) != false
123
97
  value
124
- end
125
- end
126
-
127
- # @todo: Durran: Refactor before release, but this fixes the issue with
128
- # the extra queries.
129
- def get_relation_for_set(name, metadata, object)
130
- variable = "@#{name}"
131
- value = if instance_variable_defined?(variable)
132
- instance_variable_get(variable)
133
98
  else
134
99
  _building do
135
100
  _loading do
136
- if needs_no_database_query?(object, metadata)
101
+ if object && needs_no_database_query?(object, metadata)
137
102
  __build__(name, object, metadata)
138
103
  else
139
104
  __build__(name, attributes[metadata.key], metadata)
@@ -145,7 +110,7 @@ module Mongoid
145
110
 
146
111
  def needs_no_database_query?(object, metadata)
147
112
  object.is_a?(Document) && !object.embedded? &&
148
- object.id == attributes[metadata.key]
113
+ object._id == attributes[metadata.key]
149
114
  end
150
115
 
151
116
  # Is the current code executing without autobuild functionality?
@@ -190,12 +155,11 @@ module Mongoid
190
155
  # person.game?
191
156
  #
192
157
  # @param [ String, Symbol ] name The name of the relation.
193
- # @param [ Metadata ] The metadata.
194
158
  #
195
159
  # @return [ Class ] The model being set up.
196
160
  #
197
161
  # @since 3.0.0
198
- def existence_check(name, metadata)
162
+ def existence_check(name)
199
163
  module_eval <<-END
200
164
  def #{name}?
201
165
  without_autobuild { !__send__(:#{name}).blank? }
@@ -220,7 +184,11 @@ module Mongoid
220
184
  # @since 2.0.0.rc.1
221
185
  def getter(name, metadata)
222
186
  re_define_method(name) do |reload = false|
223
- get_relation(name, metadata, reload)
187
+ value = get_relation(name, metadata, nil, reload)
188
+ if value.nil? && metadata.autobuilding? && !without_autobuild?
189
+ value = send("build_#{name}")
190
+ end
191
+ value
224
192
  end
225
193
  self
226
194
  end
@@ -232,7 +200,6 @@ module Mongoid
232
200
  # Person.ids_getter("addresses", metadata)
233
201
  #
234
202
  # @param [ String, Symbol ] name The name of the relation.
235
- # @param [ Metadata] metadata The metadata for the relation.
236
203
  #
237
204
  # @return [ Class ] The class being set up.
238
205
  def ids_getter(name, metadata)
@@ -243,7 +210,6 @@ module Mongoid
243
210
  self
244
211
  end
245
212
 
246
-
247
213
  # Defines the setter for the relation. This does a few things based on
248
214
  # some conditions. If there is an existing association, a target
249
215
  # substitution will take place, otherwise a new relation will be
@@ -261,9 +227,7 @@ module Mongoid
261
227
  def setter(name, metadata)
262
228
  re_define_method("#{name}=") do |object|
263
229
  without_autobuild do
264
- if metadata.many?
265
- set_relation(name, get_relation(name, metadata).substitute(object.substitutable))
266
- elsif value = get_relation_for_set(name, metadata, object)
230
+ if value = get_relation(name, metadata, object)
267
231
  set_relation(name, value.substitute(object.substitutable))
268
232
  else
269
233
  __build__(name, object.substitutable, metadata)