mongoid 2.4.10 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (356) hide show
  1. data/CHANGELOG.md +949 -10
  2. data/LICENSE +1 -1
  3. data/README.md +10 -11
  4. data/Rakefile +3 -17
  5. data/lib/config/locales/en.yml +455 -51
  6. data/lib/mongoid/atomic/modifiers.rb +2 -2
  7. data/lib/mongoid/atomic/paths/embedded/many.rb +6 -6
  8. data/lib/mongoid/atomic/paths/embedded/one.rb +5 -5
  9. data/lib/mongoid/atomic/paths/embedded.rb +4 -5
  10. data/lib/mongoid/atomic/paths/root.rb +4 -5
  11. data/lib/mongoid/atomic.rb +70 -16
  12. data/lib/mongoid/attributes/processing.rb +14 -10
  13. data/lib/mongoid/attributes/readonly.rb +56 -0
  14. data/lib/mongoid/attributes.rb +95 -32
  15. data/lib/mongoid/callbacks.rb +106 -43
  16. data/lib/mongoid/components.rb +12 -23
  17. data/lib/mongoid/config/environment.rb +7 -4
  18. data/lib/mongoid/config/inflections.rb +6 -0
  19. data/lib/mongoid/config/options.rb +1 -1
  20. data/lib/mongoid/config/validators/option.rb +25 -0
  21. data/lib/mongoid/config/validators/session.rb +140 -0
  22. data/lib/mongoid/config/validators.rb +3 -0
  23. data/lib/mongoid/config.rb +104 -225
  24. data/lib/mongoid/contextual/aggregable/memory.rb +109 -0
  25. data/lib/mongoid/contextual/aggregable/mongo.rb +181 -0
  26. data/lib/mongoid/contextual/atomic.rb +179 -0
  27. data/lib/mongoid/contextual/command.rb +43 -0
  28. data/lib/mongoid/contextual/find_and_modify.rb +68 -0
  29. data/lib/mongoid/contextual/map_reduce.rb +273 -0
  30. data/lib/mongoid/contextual/memory.rb +406 -0
  31. data/lib/mongoid/contextual/mongo.rb +662 -0
  32. data/lib/mongoid/contextual.rb +50 -0
  33. data/lib/mongoid/copyable.rb +7 -25
  34. data/lib/mongoid/criteria.rb +515 -245
  35. data/lib/mongoid/criterion/inspection.rb +14 -8
  36. data/lib/mongoid/criterion/scoping.rb +114 -44
  37. data/lib/mongoid/dirty.rb +152 -67
  38. data/lib/mongoid/document.rb +71 -52
  39. data/lib/mongoid/errors/ambiguous_relationship.rb +51 -0
  40. data/lib/mongoid/errors/callback.rb +5 -6
  41. data/lib/mongoid/errors/delete_restriction.rb +29 -0
  42. data/lib/mongoid/errors/document_not_found.rb +98 -17
  43. data/lib/mongoid/errors/eager_load.rb +3 -6
  44. data/lib/mongoid/errors/invalid_collection.rb +3 -3
  45. data/lib/mongoid/errors/invalid_config_option.rb +27 -0
  46. data/lib/mongoid/errors/invalid_database.rb +3 -3
  47. data/lib/mongoid/errors/invalid_field.rb +54 -8
  48. data/lib/mongoid/errors/invalid_field_option.rb +35 -0
  49. data/lib/mongoid/errors/invalid_find.rb +3 -3
  50. data/lib/mongoid/errors/invalid_index.rb +28 -0
  51. data/lib/mongoid/errors/invalid_options.rb +4 -4
  52. data/lib/mongoid/errors/invalid_scope.rb +24 -0
  53. data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +38 -0
  54. data/lib/mongoid/errors/invalid_storage_options.rb +27 -0
  55. data/lib/mongoid/errors/invalid_time.rb +3 -6
  56. data/lib/mongoid/errors/inverse_not_found.rb +29 -0
  57. data/lib/mongoid/errors/mixed_relations.rb +4 -9
  58. data/lib/mongoid/errors/mixed_session_configuration.rb +28 -0
  59. data/lib/mongoid/errors/mongoid_error.rb +54 -3
  60. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +28 -0
  61. data/lib/mongoid/errors/no_default_session.rb +23 -0
  62. data/lib/mongoid/errors/no_environment.rb +3 -3
  63. data/lib/mongoid/errors/no_map_reduce_output.rb +24 -0
  64. data/lib/mongoid/errors/no_metadata.rb +21 -0
  65. data/lib/mongoid/errors/no_parent.rb +24 -0
  66. data/lib/mongoid/errors/no_session_config.rb +22 -0
  67. data/lib/mongoid/errors/no_session_database.rb +27 -0
  68. data/lib/mongoid/errors/no_session_hosts.rb +27 -0
  69. data/lib/mongoid/errors/no_sessions_config.rb +20 -0
  70. data/lib/mongoid/errors/readonly_attribute.rb +25 -0
  71. data/lib/mongoid/errors/scope_overwrite.rb +4 -4
  72. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +4 -4
  73. data/lib/mongoid/errors/unknown_attribute.rb +25 -0
  74. data/lib/mongoid/errors/unsaved_document.rb +4 -8
  75. data/lib/mongoid/errors/unsupported_javascript.rb +27 -0
  76. data/lib/mongoid/errors/unsupported_version.rb +4 -4
  77. data/lib/mongoid/errors/validations.rb +7 -6
  78. data/lib/mongoid/errors/versioning_not_on_root.rb +23 -0
  79. data/lib/mongoid/errors.rb +23 -1
  80. data/lib/mongoid/evolvable.rb +19 -0
  81. data/lib/mongoid/extensions/array.rb +164 -0
  82. data/lib/mongoid/extensions/big_decimal.rb +42 -0
  83. data/lib/mongoid/extensions/boolean.rb +24 -0
  84. data/lib/mongoid/extensions/date.rb +70 -0
  85. data/lib/mongoid/extensions/date_time.rb +73 -0
  86. data/lib/mongoid/extensions/false_class.rb +38 -0
  87. data/lib/mongoid/extensions/float.rb +56 -0
  88. data/lib/mongoid/extensions/hash.rb +123 -0
  89. data/lib/mongoid/extensions/integer.rb +66 -0
  90. data/lib/mongoid/extensions/module.rb +28 -0
  91. data/lib/mongoid/extensions/nil_class.rb +21 -0
  92. data/lib/mongoid/extensions/object.rb +238 -0
  93. data/lib/mongoid/extensions/object_id.rb +54 -0
  94. data/lib/mongoid/extensions/range.rb +79 -0
  95. data/lib/mongoid/extensions/regexp.rb +27 -0
  96. data/lib/mongoid/extensions/set.rb +55 -0
  97. data/lib/mongoid/extensions/string.rb +181 -0
  98. data/lib/mongoid/extensions/symbol.rb +54 -0
  99. data/lib/mongoid/extensions/time.rb +78 -0
  100. data/lib/mongoid/extensions/time_with_zone.rb +55 -0
  101. data/lib/mongoid/extensions/true_class.rb +38 -0
  102. data/lib/mongoid/extensions.rb +28 -76
  103. data/lib/mongoid/factory.rb +1 -1
  104. data/lib/mongoid/fields/foreign_key.rb +150 -0
  105. data/lib/mongoid/fields/localized.rb +73 -0
  106. data/lib/mongoid/fields/standard.rb +268 -0
  107. data/lib/mongoid/fields/validators/macro.rb +83 -0
  108. data/lib/mongoid/fields/validators.rb +2 -0
  109. data/lib/mongoid/fields.rb +142 -208
  110. data/lib/mongoid/finders.rb +45 -50
  111. data/lib/mongoid/hierarchy.rb +44 -15
  112. data/lib/mongoid/identity_map.rb +49 -21
  113. data/lib/mongoid/indexes/validators/options.rb +80 -0
  114. data/lib/mongoid/indexes.rb +66 -15
  115. data/lib/mongoid/inspection.rb +1 -1
  116. data/lib/mongoid/json.rb +2 -2
  117. data/lib/mongoid/loggable.rb +69 -0
  118. data/lib/mongoid/matchers/all.rb +7 -8
  119. data/lib/mongoid/matchers/and.rb +3 -3
  120. data/lib/mongoid/matchers/default.rb +6 -4
  121. data/lib/mongoid/matchers/exists.rb +2 -2
  122. data/lib/mongoid/matchers/gt.rb +2 -2
  123. data/lib/mongoid/matchers/gte.rb +2 -2
  124. data/lib/mongoid/matchers/in.rb +3 -7
  125. data/lib/mongoid/matchers/lt.rb +2 -2
  126. data/lib/mongoid/matchers/lte.rb +2 -2
  127. data/lib/mongoid/matchers/ne.rb +2 -2
  128. data/lib/mongoid/matchers/nin.rb +2 -2
  129. data/lib/mongoid/matchers/or.rb +2 -2
  130. data/lib/mongoid/matchers/size.rb +2 -2
  131. data/lib/mongoid/matchers/strategies.rb +3 -3
  132. data/lib/mongoid/matchers.rb +1 -1
  133. data/lib/mongoid/multi_parameter_attributes.rb +9 -11
  134. data/lib/mongoid/nested_attributes.rb +17 -9
  135. data/lib/mongoid/observer.rb +1 -2
  136. data/lib/mongoid/paranoia.rb +10 -44
  137. data/lib/mongoid/persistence/atomic/add_to_set.rb +5 -9
  138. data/lib/mongoid/persistence/atomic/bit.rb +5 -7
  139. data/lib/mongoid/persistence/atomic/inc.rb +5 -7
  140. data/lib/mongoid/persistence/atomic/operation.rb +45 -6
  141. data/lib/mongoid/persistence/atomic/pop.rb +5 -7
  142. data/lib/mongoid/persistence/atomic/pull.rb +5 -7
  143. data/lib/mongoid/persistence/atomic/pull_all.rb +5 -7
  144. data/lib/mongoid/persistence/atomic/push.rb +4 -10
  145. data/lib/mongoid/persistence/atomic/push_all.rb +4 -10
  146. data/lib/mongoid/persistence/atomic/rename.rb +6 -7
  147. data/lib/mongoid/persistence/atomic/sets.rb +5 -7
  148. data/lib/mongoid/persistence/atomic/unset.rb +4 -5
  149. data/lib/mongoid/persistence/atomic.rb +2 -2
  150. data/lib/mongoid/persistence/deletion.rb +2 -2
  151. data/lib/mongoid/persistence/insertion.rb +10 -16
  152. data/lib/mongoid/persistence/modification.rb +5 -9
  153. data/lib/mongoid/persistence/operations/embedded/insert.rb +7 -6
  154. data/lib/mongoid/persistence/operations/embedded/remove.rb +5 -5
  155. data/lib/mongoid/persistence/operations/insert.rb +4 -4
  156. data/lib/mongoid/persistence/operations/remove.rb +4 -4
  157. data/lib/mongoid/persistence/operations/update.rb +5 -5
  158. data/lib/mongoid/persistence/operations/upsert.rb +28 -0
  159. data/lib/mongoid/persistence/operations.rb +22 -19
  160. data/lib/mongoid/persistence/upsertion.rb +30 -0
  161. data/lib/mongoid/persistence.rb +94 -39
  162. data/lib/mongoid/railtie.rb +26 -11
  163. data/lib/mongoid/railties/database.rake +22 -108
  164. data/lib/mongoid/relations/accessors.rb +120 -20
  165. data/lib/mongoid/relations/auto_save.rb +59 -5
  166. data/lib/mongoid/relations/binding.rb +211 -2
  167. data/lib/mongoid/relations/bindings/embedded/in.rb +16 -22
  168. data/lib/mongoid/relations/bindings/embedded/many.rb +9 -50
  169. data/lib/mongoid/relations/bindings/embedded/one.rb +10 -16
  170. data/lib/mongoid/relations/bindings/referenced/in.rb +31 -57
  171. data/lib/mongoid/relations/bindings/referenced/many.rb +8 -20
  172. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +15 -19
  173. data/lib/mongoid/relations/bindings/referenced/one.rb +10 -24
  174. data/lib/mongoid/relations/builder.rb +4 -4
  175. data/lib/mongoid/relations/builders/embedded/in.rb +5 -5
  176. data/lib/mongoid/relations/builders/embedded/many.rb +12 -12
  177. data/lib/mongoid/relations/builders/embedded/one.rb +6 -6
  178. data/lib/mongoid/relations/builders/nested_attributes/many.rb +8 -8
  179. data/lib/mongoid/relations/builders/nested_attributes/one.rb +5 -5
  180. data/lib/mongoid/relations/builders/referenced/in.rb +4 -4
  181. data/lib/mongoid/relations/builders/referenced/many.rb +6 -6
  182. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +7 -5
  183. data/lib/mongoid/relations/builders/referenced/one.rb +5 -5
  184. data/lib/mongoid/relations/builders.rb +19 -16
  185. data/lib/mongoid/relations/cascading/delete.rb +3 -5
  186. data/lib/mongoid/relations/cascading/destroy.rb +3 -3
  187. data/lib/mongoid/relations/cascading/nullify.rb +3 -3
  188. data/lib/mongoid/relations/cascading/restrict.rb +37 -0
  189. data/lib/mongoid/relations/cascading.rb +10 -7
  190. data/lib/mongoid/relations/constraint.rb +4 -3
  191. data/lib/mongoid/relations/conversions.rb +6 -7
  192. data/lib/mongoid/relations/cyclic.rb +7 -7
  193. data/lib/mongoid/relations/embedded/batchable.rb +347 -0
  194. data/lib/mongoid/relations/embedded/in.rb +23 -12
  195. data/lib/mongoid/relations/embedded/many.rb +100 -161
  196. data/lib/mongoid/relations/embedded/one.rb +25 -14
  197. data/lib/mongoid/relations/macros.rb +105 -60
  198. data/lib/mongoid/relations/many.rb +93 -14
  199. data/lib/mongoid/relations/metadata.rb +277 -47
  200. data/lib/mongoid/relations/nested_builder.rb +4 -6
  201. data/lib/mongoid/relations/one.rb +2 -2
  202. data/lib/mongoid/relations/options.rb +2 -2
  203. data/lib/mongoid/relations/polymorphic.rb +9 -9
  204. data/lib/mongoid/relations/proxy.rb +62 -31
  205. data/lib/mongoid/relations/referenced/in.rb +40 -15
  206. data/lib/mongoid/relations/referenced/many.rb +162 -130
  207. data/lib/mongoid/relations/referenced/many_to_many.rb +104 -48
  208. data/lib/mongoid/relations/referenced/one.rb +34 -13
  209. data/lib/mongoid/relations/reflections.rb +3 -3
  210. data/lib/mongoid/relations/synchronization.rb +19 -23
  211. data/lib/mongoid/relations/targets/enumerable.rb +86 -57
  212. data/lib/mongoid/relations/touchable.rb +32 -0
  213. data/lib/mongoid/relations.rb +22 -6
  214. data/lib/mongoid/reloading.rb +12 -14
  215. data/lib/mongoid/scoping.rb +312 -0
  216. data/lib/mongoid/serialization.rb +94 -42
  217. data/lib/mongoid/sessions/factory.rb +108 -0
  218. data/lib/mongoid/sessions/mongo_uri.rb +93 -0
  219. data/lib/mongoid/sessions/validators/storage.rb +49 -0
  220. data/lib/mongoid/sessions/validators.rb +2 -0
  221. data/lib/mongoid/sessions.rb +383 -0
  222. data/lib/mongoid/sharding.rb +6 -6
  223. data/lib/mongoid/state.rb +6 -7
  224. data/lib/mongoid/threaded/lifecycle.rb +21 -21
  225. data/lib/mongoid/threaded/sessions.rb +0 -0
  226. data/lib/mongoid/threaded.rb +219 -59
  227. data/lib/mongoid/timestamps/created.rb +8 -4
  228. data/lib/mongoid/timestamps/timeless.rb +6 -4
  229. data/lib/mongoid/timestamps/updated.rb +4 -3
  230. data/lib/mongoid/timestamps.rb +1 -1
  231. data/lib/mongoid/unit_of_work.rb +61 -0
  232. data/lib/mongoid/validations/associated.rb +2 -2
  233. data/lib/mongoid/validations/format.rb +2 -2
  234. data/lib/mongoid/validations/presence.rb +34 -4
  235. data/lib/mongoid/validations/uniqueness.rb +11 -12
  236. data/lib/mongoid/validations.rb +28 -20
  237. data/lib/mongoid/version.rb +2 -2
  238. data/lib/mongoid/versioning.rb +25 -26
  239. data/lib/mongoid.rb +37 -37
  240. data/lib/rack/mongoid/middleware/identity_map.rb +3 -3
  241. data/lib/rails/generators/mongoid/config/config_generator.rb +1 -1
  242. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +65 -17
  243. data/lib/rails/generators/mongoid/model/model_generator.rb +7 -7
  244. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +2 -2
  245. data/lib/rails/generators/mongoid/observer/observer_generator.rb +4 -4
  246. data/lib/rails/generators/mongoid_generator.rb +5 -5
  247. data/lib/rails/mongoid.rb +73 -26
  248. metadata +103 -148
  249. data/lib/config/locales/bg.yml +0 -61
  250. data/lib/config/locales/de.yml +0 -61
  251. data/lib/config/locales/en-GB.yml +0 -64
  252. data/lib/config/locales/es.yml +0 -59
  253. data/lib/config/locales/fr.yml +0 -62
  254. data/lib/config/locales/hi.yml +0 -53
  255. data/lib/config/locales/hu.yml +0 -64
  256. data/lib/config/locales/id.yml +0 -62
  257. data/lib/config/locales/it.yml +0 -59
  258. data/lib/config/locales/ja.yml +0 -57
  259. data/lib/config/locales/kr.yml +0 -54
  260. data/lib/config/locales/nl.yml +0 -61
  261. data/lib/config/locales/pl.yml +0 -59
  262. data/lib/config/locales/pt-BR.yml +0 -60
  263. data/lib/config/locales/pt.yml +0 -60
  264. data/lib/config/locales/ro.yml +0 -66
  265. data/lib/config/locales/ru.yml +0 -61
  266. data/lib/config/locales/sv.yml +0 -60
  267. data/lib/config/locales/vi.yml +0 -62
  268. data/lib/config/locales/zh-CN.yml +0 -53
  269. data/lib/mongoid/collection.rb +0 -157
  270. data/lib/mongoid/collections/master.rb +0 -45
  271. data/lib/mongoid/collections/operations.rb +0 -44
  272. data/lib/mongoid/collections/retry.rb +0 -59
  273. data/lib/mongoid/collections.rb +0 -120
  274. data/lib/mongoid/config/database.rb +0 -181
  275. data/lib/mongoid/config/replset_database.rb +0 -80
  276. data/lib/mongoid/contexts/enumerable/sort.rb +0 -43
  277. data/lib/mongoid/contexts/enumerable.rb +0 -313
  278. data/lib/mongoid/contexts/mongo.rb +0 -487
  279. data/lib/mongoid/contexts.rb +0 -25
  280. data/lib/mongoid/criterion/builder.rb +0 -34
  281. data/lib/mongoid/criterion/complex.rb +0 -84
  282. data/lib/mongoid/criterion/creational.rb +0 -34
  283. data/lib/mongoid/criterion/exclusion.rb +0 -108
  284. data/lib/mongoid/criterion/inclusion.rb +0 -290
  285. data/lib/mongoid/criterion/optional.rb +0 -259
  286. data/lib/mongoid/criterion/selector.rb +0 -177
  287. data/lib/mongoid/cursor.rb +0 -88
  288. data/lib/mongoid/default_scope.rb +0 -36
  289. data/lib/mongoid/errors/invalid_type.rb +0 -25
  290. data/lib/mongoid/extensions/array/deep_copy.rb +0 -25
  291. data/lib/mongoid/extensions/array/deletion.rb +0 -29
  292. data/lib/mongoid/extensions/false_class/equality.rb +0 -26
  293. data/lib/mongoid/extensions/hash/criteria_helpers.rb +0 -47
  294. data/lib/mongoid/extensions/hash/deep_copy.rb +0 -25
  295. data/lib/mongoid/extensions/hash/scoping.rb +0 -25
  296. data/lib/mongoid/extensions/integer/checks.rb +0 -23
  297. data/lib/mongoid/extensions/nil/collectionization.rb +0 -23
  298. data/lib/mongoid/extensions/object/checks.rb +0 -29
  299. data/lib/mongoid/extensions/object/deep_copy.rb +0 -21
  300. data/lib/mongoid/extensions/object/reflections.rb +0 -48
  301. data/lib/mongoid/extensions/object/substitutable.rb +0 -15
  302. data/lib/mongoid/extensions/object/yoda.rb +0 -44
  303. data/lib/mongoid/extensions/object_id/conversions.rb +0 -60
  304. data/lib/mongoid/extensions/proc/scoping.rb +0 -25
  305. data/lib/mongoid/extensions/string/checks.rb +0 -36
  306. data/lib/mongoid/extensions/string/conversions.rb +0 -22
  307. data/lib/mongoid/extensions/string/inflections.rb +0 -118
  308. data/lib/mongoid/extensions/symbol/checks.rb +0 -23
  309. data/lib/mongoid/extensions/symbol/inflections.rb +0 -67
  310. data/lib/mongoid/extensions/true_class/equality.rb +0 -26
  311. data/lib/mongoid/extras.rb +0 -31
  312. data/lib/mongoid/fields/internal/array.rb +0 -76
  313. data/lib/mongoid/fields/internal/big_decimal.rb +0 -63
  314. data/lib/mongoid/fields/internal/bignum.rb +0 -10
  315. data/lib/mongoid/fields/internal/binary.rb +0 -11
  316. data/lib/mongoid/fields/internal/boolean.rb +0 -58
  317. data/lib/mongoid/fields/internal/date.rb +0 -51
  318. data/lib/mongoid/fields/internal/date_time.rb +0 -28
  319. data/lib/mongoid/fields/internal/false_class.rb +0 -10
  320. data/lib/mongoid/fields/internal/fixnum.rb +0 -10
  321. data/lib/mongoid/fields/internal/float.rb +0 -47
  322. data/lib/mongoid/fields/internal/foreign_keys/array.rb +0 -88
  323. data/lib/mongoid/fields/internal/foreign_keys/object.rb +0 -56
  324. data/lib/mongoid/fields/internal/hash.rb +0 -11
  325. data/lib/mongoid/fields/internal/integer.rb +0 -59
  326. data/lib/mongoid/fields/internal/localized.rb +0 -62
  327. data/lib/mongoid/fields/internal/nil_class.rb +0 -53
  328. data/lib/mongoid/fields/internal/object.rb +0 -11
  329. data/lib/mongoid/fields/internal/object_id.rb +0 -46
  330. data/lib/mongoid/fields/internal/range.rb +0 -61
  331. data/lib/mongoid/fields/internal/set.rb +0 -57
  332. data/lib/mongoid/fields/internal/string.rb +0 -42
  333. data/lib/mongoid/fields/internal/symbol.rb +0 -43
  334. data/lib/mongoid/fields/internal/time.rb +0 -23
  335. data/lib/mongoid/fields/internal/time_with_zone.rb +0 -23
  336. data/lib/mongoid/fields/internal/timekeeping.rb +0 -122
  337. data/lib/mongoid/fields/internal/true_class.rb +0 -10
  338. data/lib/mongoid/fields/mappings.rb +0 -42
  339. data/lib/mongoid/fields/serializable.rb +0 -270
  340. data/lib/mongoid/identity.rb +0 -92
  341. data/lib/mongoid/javascript/functions.yml +0 -63
  342. data/lib/mongoid/javascript.rb +0 -20
  343. data/lib/mongoid/keys.rb +0 -144
  344. data/lib/mongoid/logger.rb +0 -45
  345. data/lib/mongoid/multi_database.rb +0 -36
  346. data/lib/mongoid/named_scope.rb +0 -166
  347. data/lib/mongoid/relations/embedded/atomic/operation.rb +0 -63
  348. data/lib/mongoid/relations/embedded/atomic/pull.rb +0 -65
  349. data/lib/mongoid/relations/embedded/atomic/push_all.rb +0 -59
  350. data/lib/mongoid/relations/embedded/atomic/set.rb +0 -61
  351. data/lib/mongoid/relations/embedded/atomic/unset.rb +0 -41
  352. data/lib/mongoid/relations/embedded/atomic.rb +0 -89
  353. data/lib/mongoid/relations/referenced/batch/insert.rb +0 -57
  354. data/lib/mongoid/relations/referenced/batch.rb +0 -73
  355. data/lib/mongoid/safety.rb +0 -105
  356. data/lib/mongoid/scope.rb +0 -31
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
- module Mongoid # :nodoc:
3
- module Relations #:nodoc:
4
- module Referenced #:nodoc:
2
+ module Mongoid
3
+ module Relations
4
+ module Referenced
5
5
 
6
6
  # This class handles all behaviour for relations that are either
7
7
  # one-to-many or one-to-one, where the foreign key is store on this side
@@ -25,6 +25,18 @@ module Mongoid # :nodoc:
25
25
  end
26
26
  end
27
27
 
28
+ # Removes the association between the base document and the target
29
+ # document by deleting the foreign key and the reference, orphaning
30
+ # the target document in the process.
31
+ #
32
+ # @example Nullify the relation.
33
+ # person.game.nullify
34
+ #
35
+ def nullify
36
+ unbind_one
37
+ target.save
38
+ end
39
+
28
40
  # Substitutes the supplied target documents for the existing document
29
41
  # in the relation.
30
42
  #
@@ -38,12 +50,11 @@ module Mongoid # :nodoc:
38
50
  #
39
51
  # @since 2.0.0.rc.1
40
52
  def substitute(replacement)
41
- tap do |proxy|
42
- proxy.unbind_one
43
- return nil unless replacement
44
- proxy.target = replacement
45
- proxy.bind_one
46
- end
53
+ unbind_one
54
+ return nil unless replacement
55
+ self.target = replacement
56
+ bind_one
57
+ self
47
58
  end
48
59
 
49
60
  private
@@ -107,7 +118,7 @@ module Mongoid # :nodoc:
107
118
  #
108
119
  # @since 2.1.0
109
120
  def criteria(metadata, object, type = nil)
110
- type.where(:_id => object)
121
+ type.where(_id: object)
111
122
  end
112
123
 
113
124
  # Get the criteria that is used to eager load a relation of this
@@ -124,8 +135,8 @@ module Mongoid # :nodoc:
124
135
  # @since 2.2.0
125
136
  def eager_load(metadata, ids)
126
137
  raise Errors::EagerLoad.new(metadata.name) if metadata.polymorphic?
127
- klass, foreign_key = metadata.klass, metadata.foreign_key
128
- klass.any_in("_id" => ids).each do |doc|
138
+ klass, _ = metadata.klass, metadata.foreign_key
139
+ klass.any_in("_id" => ids.uniq).each do |doc|
129
140
  IdentityMap.set(doc)
130
141
  end
131
142
  end
@@ -143,6 +154,20 @@ module Mongoid # :nodoc:
143
154
  false
144
155
  end
145
156
 
157
+ # Get the foreign key for the provided name.
158
+ #
159
+ # @example Get the foreign key.
160
+ # Referenced::In.foreign_key(:person)
161
+ #
162
+ # @param [ Symbol ] name The name.
163
+ #
164
+ # @return [ String ] The foreign key.
165
+ #
166
+ # @since 3.0.0
167
+ def foreign_key(name)
168
+ "#{name}#{foreign_key_suffix}"
169
+ end
170
+
146
171
  # Get the default value for the foreign key.
147
172
  #
148
173
  # @example Get the default.
@@ -173,9 +198,9 @@ module Mongoid # :nodoc:
173
198
  # @example Get the macro.
174
199
  # Referenced::In.macro
175
200
  #
176
- # @return [ Symbol ] :referenced_in
201
+ # @return [ Symbol ] :belongs_to
177
202
  def macro
178
- :referenced_in
203
+ :belongs_to
179
204
  end
180
205
 
181
206
  # Return the nested builder that is responsible for generating the documents
@@ -240,7 +265,7 @@ module Mongoid # :nodoc:
240
265
  #
241
266
  # @since 2.1.0
242
267
  def valid_options
243
- [ :autosave, :foreign_key, :index, :polymorphic ]
268
+ [ :autobuild, :autosave, :dependent, :foreign_key, :index, :polymorphic, :touch ]
244
269
  end
245
270
 
246
271
  # Get the default validation setting for the relation. Determines if
@@ -1,15 +1,14 @@
1
1
  # encoding: utf-8
2
- module Mongoid #:nodoc:
3
- module Relations #:nodoc:
4
- module Referenced #:nodoc:
2
+ module Mongoid
3
+ module Relations
4
+ module Referenced
5
5
 
6
6
  # This class defines the behaviour for all relations that are a
7
7
  # one-to-many between documents in different collections.
8
8
  class Many < Relations::Many
9
- include Batch
10
9
 
11
- delegate :count, :to => :criteria
12
- delegate :first, :in_memory, :last, :reset, :uniq, :to => :target
10
+ delegate :count, to: :criteria
11
+ delegate :first, :in_memory, :last, :reset, :uniq, to: :target
13
12
 
14
13
  # Appends a document or array of documents to the relation. Will set
15
14
  # the parent and update the index in the process.
@@ -35,17 +34,13 @@ module Mongoid #:nodoc:
35
34
  append(doc)
36
35
  doc.save if persistable? && !_assigning? && !doc.validated?
37
36
  end
37
+ self
38
38
  end
39
39
  alias :push :<<
40
40
 
41
41
  # Appends an array of documents to the relation. Performs a batch
42
42
  # insert of the documents instead of persisting one at a time.
43
43
  #
44
- # @note When performing batch inserts the *after* callbacks will get
45
- # executed before the documents have actually been persisted to the
46
- # database due to an issue with Active Support's callback system - we
47
- # cannot explicitly fire the after callbacks by themselves.
48
- #
49
44
  # @example Concat with other documents.
50
45
  # person.posts.concat([ post_one, post_two ])
51
46
  #
@@ -55,13 +50,14 @@ module Mongoid #:nodoc:
55
50
  #
56
51
  # @since 2.4.0
57
52
  def concat(documents)
58
- batched do
59
- documents.each do |doc|
60
- next unless doc
61
- append(doc)
62
- doc.save if persistable?
63
- end
53
+ docs, inserts = [], []
54
+ documents.each do |doc|
55
+ next unless doc
56
+ append(doc)
57
+ save_or_delay(doc, docs, inserts) if persistable?
64
58
  end
59
+ persist_delayed(docs, inserts)
60
+ self
65
61
  end
66
62
 
67
63
  # Build a new document from the attributes and append it to this
@@ -87,66 +83,15 @@ module Mongoid #:nodoc:
87
83
  options, type = {}, options
88
84
  end
89
85
 
90
- Factory.build(type || klass, attributes, options).tap do |doc|
91
- append(doc)
92
- doc.apply_proc_defaults
93
- yield(doc) if block_given?
94
- doc.run_callbacks(:build) { doc }
95
- end
86
+ doc = Factory.build(type || klass, attributes, options)
87
+ append(doc)
88
+ doc.apply_post_processed_defaults
89
+ yield(doc) if block_given?
90
+ doc.run_callbacks(:build) { doc }
91
+ doc
96
92
  end
97
93
  alias :new :build
98
94
 
99
- # Creates a new document on the references many relation. This will
100
- # save the document if the parent has been persisted.
101
- #
102
- # @example Create and save the new document.
103
- # person.posts.create(:text => "Testing")
104
- #
105
- # @overload create(attributes = nil, options = {}, type = nil)
106
- # @param [ Hash ] attributes The attributes to create with.
107
- # @param [ Hash ] options The scoped assignment options.
108
- # @param [ Class ] type The optional type of document to create.
109
- #
110
- # @overload create(attributes = nil, type = nil)
111
- # @param [ Hash ] attributes The attributes to create with.
112
- # @param [ Class ] type The optional type of document to create.
113
- #
114
- # @return [ Document ] The newly created document.
115
- #
116
- # @since 2.0.0.beta.1
117
- def create(attributes = nil, options = {}, type = nil, &block)
118
- build(attributes, options, type, &block).tap do |doc|
119
- base.persisted? ? doc.save : raise_unsaved(doc)
120
- end
121
- end
122
-
123
- # Creates a new document on the references many relation. This will
124
- # save the document if the parent has been persisted and will raise an
125
- # error if validation fails.
126
- #
127
- # @example Create and save the new document.
128
- # person.posts.create!(:text => "Testing")
129
- #
130
- # @overload create!(attributes = nil, options = {}, type = nil)
131
- # @param [ Hash ] attributes The attributes to create with.
132
- # @param [ Hash ] options The scoped assignment options.
133
- # @param [ Class ] type The optional type of document to create.
134
- #
135
- # @overload create!(attributes = nil, type = nil)
136
- # @param [ Hash ] attributes The attributes to create with.
137
- # @param [ Class ] type The optional type of document to create.
138
- #
139
- # @raise [ Errors::Validations ] If validation failed.
140
- #
141
- # @return [ Document ] The newly created document.
142
- #
143
- # @since 2.0.0.beta.1
144
- def create!(attributes = nil, options = {}, type = nil, &block)
145
- build(attributes, options, type, &block).tap do |doc|
146
- base.persisted? ? doc.save! : raise_unsaved(doc)
147
- end
148
- end
149
-
150
95
  # Delete the document from the relation. This will set the foreign key
151
96
  # on the document to nil. If the dependent options on the relation are
152
97
  # :delete or :destroy the appropriate removal will occur.
@@ -175,7 +120,7 @@ module Mongoid #:nodoc:
175
120
  # person.posts.delete_all
176
121
  #
177
122
  # @example Conditonally delete all documents in the relation.
178
- # person.posts.delete_all(:conditions => { :title => "Testing" })
123
+ # person.posts.delete_all({ :title => "Testing" })
179
124
  #
180
125
  # @param [ Hash ] conditions Optional conditions to delete with.
181
126
  #
@@ -193,7 +138,7 @@ module Mongoid #:nodoc:
193
138
  # person.posts.destroy_all
194
139
  #
195
140
  # @example Conditonally destroy all documents in the relation.
196
- # person.posts.destroy_all(:conditions => { :title => "Testing" })
141
+ # person.posts.destroy_all({ :title => "Testing" })
197
142
  #
198
143
  # @param [ Hash ] conditions Optional conditions to destroy with.
199
144
  #
@@ -225,23 +170,12 @@ module Mongoid #:nodoc:
225
170
  # conditions.
226
171
  #
227
172
  # @example Find by an id.
228
- # person.posts.find(BSON::ObjectId.new)
173
+ # person.posts.find(Moped::BSON::ObjectId.new)
229
174
  #
230
175
  # @example Find by multiple ids.
231
- # person.posts.find([ BSON::ObjectId.new, BSON::ObjectId.new ])
176
+ # person.posts.find([ Moped::BSON::ObjectId.new, Moped::BSON::ObjectId.new ])
232
177
  #
233
- # @example Conditionally find all matching documents.
234
- # person.posts.find(:all, :conditions => { :title => "Sir" })
235
- #
236
- # @example Conditionally find the first document.
237
- # person.posts.find(:first, :conditions => { :title => "Sir" })
238
- #
239
- # @example Conditionally find the last document.
240
- # person.posts.find(:last, :conditions => { :title => "Sir" })
241
- #
242
- # @param [ Symbol, BSON::ObjectId, Array<BSON::ObjectId> ] arg The
243
- # argument to search with.
244
- # @param [ Hash ] options The options to search with.
178
+ # @param [ Moped::BSON::ObjectId, Array<Moped::BSON::ObjectId> ] arg The ids.
245
179
  #
246
180
  # @return [ Document, Criteria ] The matching document(s).
247
181
  #
@@ -276,7 +210,7 @@ module Mongoid #:nodoc:
276
210
  #
277
211
  # @since 2.0.0.rc.1
278
212
  def nullify
279
- criteria.update(metadata.foreign_key => nil)
213
+ criteria.update(foreign_key => nil)
280
214
  target.clear do |doc|
281
215
  unbind_one(doc)
282
216
  end
@@ -318,19 +252,18 @@ module Mongoid #:nodoc:
318
252
  #
319
253
  # @since 2.0.0.rc.1
320
254
  def substitute(replacement)
321
- tap do |proxy|
322
- if replacement
323
- new_docs, docs = replacement.compact.uniq, []
324
- new_ids = new_docs.map { |doc| doc.id }
325
- remove_not_in(new_ids)
326
- new_docs.each do |doc|
327
- docs.push(doc) if doc.send(metadata.foreign_key) != base.id
328
- end
329
- proxy.concat(docs)
330
- else
331
- proxy.purge
255
+ if replacement
256
+ new_docs, docs = replacement.compact, []
257
+ new_ids = new_docs.map { |doc| doc.id }
258
+ remove_not_in(new_ids)
259
+ new_docs.each do |doc|
260
+ docs.push(doc) if doc.send(foreign_key) != base.id
332
261
  end
262
+ concat(docs)
263
+ else
264
+ purge
333
265
  end
266
+ self
334
267
  end
335
268
 
336
269
  # Get a criteria for the documents without the default scoping
@@ -344,7 +277,7 @@ module Mongoid #:nodoc:
344
277
  # @since 2.4.0
345
278
  def unscoped
346
279
  klass.unscoped.where(
347
- metadata.foreign_key => Conversions.flag(base.id, metadata)
280
+ foreign_key => Conversions.flag(base.id, metadata)
348
281
  )
349
282
  end
350
283
 
@@ -401,7 +334,7 @@ module Mongoid #:nodoc:
401
334
  #
402
335
  # @since 2.0.0.beta.1
403
336
  def criteria
404
- Many.criteria(metadata, Conversions.flag(base.id, metadata))
337
+ Many.criteria(metadata, Conversions.flag(base.id, metadata), base.class)
405
338
  end
406
339
 
407
340
  # Perform the necessary cascade operations for documents that just got
@@ -447,6 +380,28 @@ module Mongoid #:nodoc:
447
380
  end
448
381
  end
449
382
 
383
+ # Persist all the delayed batch inserts.
384
+ #
385
+ # @api private
386
+ #
387
+ # @example Persist the delayed batch inserts.
388
+ # relation.persist_delayed([ doc ])
389
+ #
390
+ # @param [ Array<Document> ] docs The delayed inserts.
391
+ # @param [ Array<Hash> ] inserts The raw insert document.
392
+ #
393
+ # @since 3.0.0
394
+ def persist_delayed(docs, inserts)
395
+ unless docs.empty?
396
+ collection.insert(inserts)
397
+ docs.each do |doc|
398
+ doc.new_record = false
399
+ doc.run_after_callbacks(:create, :save)
400
+ doc.post_persist
401
+ end
402
+ end
403
+ end
404
+
450
405
  # Are we able to persist this relation?
451
406
  #
452
407
  # @example Can we persist the relation?
@@ -466,7 +421,7 @@ module Mongoid #:nodoc:
466
421
  # person.posts.delete_all
467
422
  #
468
423
  # @example Conditonally delete all documents in the relation.
469
- # person.posts.delete_all(:conditions => { :title => "Testing" })
424
+ # person.posts.delete_all({ :title => "Testing" })
470
425
  #
471
426
  # @param [ Hash ] conditions Optional conditions to delete with.
472
427
  # @param [ Symbol ] The deletion method to call.
@@ -475,21 +430,19 @@ module Mongoid #:nodoc:
475
430
  #
476
431
  # @since 2.1.0
477
432
  def remove_all(conditions = nil, method = :delete_all)
478
- selector = (conditions || {})[:conditions] || {}
479
- klass.send(method, :conditions => selector.merge!(criteria.selector)).tap do
480
- target.delete_if do |doc|
481
- if doc.matches?(selector)
482
- unbind_one(doc) and true
483
- end
433
+ selector = conditions || {}
434
+ removed = klass.send(method, selector.merge!(criteria.selector))
435
+ target.delete_if do |doc|
436
+ if doc.matches?(selector)
437
+ unbind_one(doc) and true
484
438
  end
485
439
  end
440
+ removed
486
441
  end
487
442
 
488
443
  # Remove all the documents in the proxy that do not have the provided
489
444
  # ids.
490
445
  #
491
- # @todo: Durran: Refactor 3.0. Temp for bug fix in 2.4.
492
- #
493
446
  # @example Remove all documents without the ids.
494
447
  # proxy.remove_not_in([ id ])
495
448
  #
@@ -497,17 +450,16 @@ module Mongoid #:nodoc:
497
450
  #
498
451
  # @since 2.4.0
499
452
  def remove_not_in(ids)
500
- removed = criteria.not_in(:_id => ids)
453
+ removed = criteria.not_in(_id: ids)
501
454
  if metadata.destructive?
502
455
  removed.delete_all
503
456
  else
504
- removed.update(metadata.foreign_key => nil)
457
+ removed.update(foreign_key => nil)
505
458
  end
506
459
  in_memory.each do |doc|
507
460
  if !ids.include?(doc.id)
508
461
  unbind_one(doc)
509
- added.try { |p| p.delete_one(doc) }
510
- loaded.try { |p| p.delete_one(doc) }
462
+ target.delete(doc)
511
463
  if metadata.destructive?
512
464
  doc.destroyed = true
513
465
  end
@@ -515,6 +467,28 @@ module Mongoid #:nodoc:
515
467
  end
516
468
  end
517
469
 
470
+ # Save a persisted document immediately or delay a new document for
471
+ # batch insert.
472
+ #
473
+ # @api private
474
+ #
475
+ # @example Save or delay the document.
476
+ # relation.save_or_delay(doc, [])
477
+ #
478
+ # @param [ Document ] doc The document.
479
+ # @param [ Array<Document> ] inserts The inserts.
480
+ #
481
+ # @since 3.0.0
482
+ def save_or_delay(doc, docs, inserts)
483
+ if doc.new_record? && doc.valid?(:create)
484
+ doc.run_before_callbacks(:save, :create)
485
+ docs.push(doc)
486
+ inserts.push(doc.as_document)
487
+ else
488
+ doc.save
489
+ end
490
+ end
491
+
518
492
  class << self
519
493
 
520
494
  # Return the builder that is responsible for generating the documents
@@ -548,7 +522,14 @@ module Mongoid #:nodoc:
548
522
  #
549
523
  # @since 2.1.0
550
524
  def criteria(metadata, object, type = nil)
551
- metadata.klass.where(metadata.foreign_key => object)
525
+ with_inverse_field_criterion(
526
+ with_polymorphic_criterion(
527
+ metadata.klass.where(metadata.foreign_key => object),
528
+ metadata,
529
+ type
530
+ ),
531
+ metadata
532
+ )
552
533
  end
553
534
 
554
535
  # Eager load the relation based on the criteria.
@@ -563,16 +544,7 @@ module Mongoid #:nodoc:
563
544
  #
564
545
  # @since 2.2.0
565
546
  def eager_load(metadata, ids)
566
- cleared = false
567
- klass, foreign_key = metadata.klass, metadata.foreign_key
568
- klass.any_in(foreign_key => ids).each do |doc|
569
- base_id = doc.send(foreign_key)
570
- unless cleared
571
- IdentityMap.clear_many(klass, foreign_key => base_id)
572
- cleared = true
573
- end
574
- IdentityMap.set_many(doc, foreign_key => base_id)
575
- end
547
+ eager_load_ids(metadata, ids) { |doc, key| IdentityMap.set_many(doc, key) }
576
548
  end
577
549
 
578
550
  # Returns true if the relation is an embedded one. In this case
@@ -588,6 +560,20 @@ module Mongoid #:nodoc:
588
560
  false
589
561
  end
590
562
 
563
+ # Get the foreign key for the provided name.
564
+ #
565
+ # @example Get the foreign key.
566
+ # Referenced::Many.foreign_key(:person)
567
+ #
568
+ # @param [ Symbol ] name The name.
569
+ #
570
+ # @return [ String ] The foreign key.
571
+ #
572
+ # @since 3.0.0
573
+ def foreign_key(name)
574
+ "#{name}#{foreign_key_suffix}"
575
+ end
576
+
591
577
  # Get the default value for the foreign key.
592
578
  #
593
579
  # @example Get the default.
@@ -618,9 +604,9 @@ module Mongoid #:nodoc:
618
604
  # @example Get the macro.
619
605
  # Referenced::Many.macro
620
606
  #
621
- # @return [ Symbol ] :references_many
607
+ # @return [ Symbol ] :has_many
622
608
  def macro
623
- :references_many
609
+ :has_many
624
610
  end
625
611
 
626
612
  # Return the nested builder that is responsible for generating the documents
@@ -700,6 +686,52 @@ module Mongoid #:nodoc:
700
686
  def validation_default
701
687
  true
702
688
  end
689
+
690
+ private
691
+
692
+ # Decorate the criteria with polymorphic criteria, if applicable.
693
+ #
694
+ # @api private
695
+ #
696
+ # @example Get the criteria with polymorphic criterion.
697
+ # Proxy.with_polymorphic_criterion(criteria, metadata)
698
+ #
699
+ # @param [ Criteria ] criteria The criteria to decorate.
700
+ # @param [ Metadata ] metadata The metadata.
701
+ # @param [ Class ] type The optional type.
702
+ #
703
+ # @return [ Criteria ] The criteria.
704
+ #
705
+ # @since 3.0.0
706
+ def with_polymorphic_criterion(criteria, metadata, type = nil)
707
+ if metadata.polymorphic?
708
+ criteria.where(metadata.type => type.name)
709
+ else
710
+ criteria
711
+ end
712
+ end
713
+
714
+ # Decorate the criteria with inverse field criteria, if applicable.
715
+ #
716
+ # @api private
717
+ #
718
+ # @example Get the criteria with polymorphic criterion.
719
+ # Proxy.with_inverse_field_criterion(criteria, metadata)
720
+ #
721
+ # @param [ Criteria ] criteria The criteria to decorate.
722
+ # @param [ Metadata ] metadata The metadata.
723
+ #
724
+ # @return [ Criteria ] The criteria.
725
+ #
726
+ # @since 3.0.0
727
+ def with_inverse_field_criterion(criteria, metadata)
728
+ inverse_metadata = metadata.inverse_metadata(metadata.klass)
729
+ if inverse_metadata.try(:inverse_of_field)
730
+ criteria.any_in(inverse_metadata.inverse_of_field => [ metadata.name, nil ])
731
+ else
732
+ criteria
733
+ end
734
+ end
703
735
  end
704
736
  end
705
737
  end