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,8 +1,8 @@
1
1
  # encoding: utf-8
2
- module Mongoid #:nodoc:
3
- module Atomic #:nodoc:
4
- module Paths #:nodoc:
5
- module Embedded #:nodoc:
2
+ module Mongoid
3
+ module Atomic
4
+ module Paths
5
+ module Embedded
6
6
 
7
7
  # This class encapsulates behaviour for locating and updating
8
8
  # documents that are defined as an embedded 1-1.
@@ -34,7 +34,7 @@ module Mongoid #:nodoc:
34
34
  # @since 2.1.0
35
35
  def position
36
36
  pos = parent.atomic_position
37
- "#{pos}#{"." unless pos.blank?}#{document.metadata.name}"
37
+ "#{pos}#{"." unless pos.blank?}#{document.metadata.store_as}"
38
38
  end
39
39
  end
40
40
  end
@@ -2,9 +2,9 @@
2
2
  require "mongoid/atomic/paths/embedded/one"
3
3
  require "mongoid/atomic/paths/embedded/many"
4
4
 
5
- module Mongoid #:nodoc:
6
- module Atomic #:nodoc:
7
- module Paths #:nodoc:
5
+ module Mongoid
6
+ module Atomic
7
+ module Paths
8
8
 
9
9
  # Common functionality between the two different embedded paths.
10
10
  module Embedded
@@ -34,8 +34,7 @@ module Mongoid #:nodoc:
34
34
  # @since 2.1.0
35
35
  def selector
36
36
  parent.atomic_selector.
37
- merge!({ "#{path}._id" => document.identifier || document._id }).
38
- merge!(document.shard_key_selector)
37
+ merge!({ "#{path}._id" => document._id }).merge!(document.shard_key_selector)
39
38
  end
40
39
  end
41
40
  end
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
- module Mongoid #:nodoc:
3
- module Atomic #:nodoc:
4
- module Paths #:nodoc:
2
+ module Mongoid
3
+ module Atomic
4
+ module Paths
5
5
 
6
6
  # This class encapsulates behaviour for locating and updating root
7
7
  # documents atomically.
@@ -31,8 +31,7 @@ module Mongoid #:nodoc:
31
31
  #
32
32
  # @since 2.1.0
33
33
  def selector
34
- { "_id" => document.identifier || document._id }.
35
- merge!(document.shard_key_selector)
34
+ { "_id" => document._id }.merge!(document.shard_key_selector)
36
35
  end
37
36
  end
38
37
  end
@@ -2,7 +2,7 @@
2
2
  require "mongoid/atomic/modifiers"
3
3
  require "mongoid/atomic/paths"
4
4
 
5
- module Mongoid #:nodoc:
5
+ module Mongoid
6
6
 
7
7
  # This module contains the logic for supporting atomic operations against the
8
8
  # database.
@@ -14,9 +14,9 @@ module Mongoid #:nodoc:
14
14
  :atomic_array_pulls,
15
15
  :atomic_array_add_to_sets,
16
16
  :atomic_pulls,
17
- :atomic_unsets,
18
17
  :delayed_atomic_sets,
19
- :delayed_atomic_pulls
18
+ :delayed_atomic_pulls,
19
+ :delayed_atomic_unsets
20
20
  ]
21
21
 
22
22
  included do
@@ -36,7 +36,22 @@ module Mongoid #:nodoc:
36
36
  # @since 2.2.0
37
37
  def add_atomic_pull(document)
38
38
  document.flagged_for_destroy = true
39
- (delayed_atomic_pulls[document.metadata.name.to_s] ||= []).push(document)
39
+ (delayed_atomic_pulls[document.metadata_name.to_s] ||= []).push(document)
40
+ end
41
+
42
+ # Add an atomic unset for the document.
43
+ #
44
+ # @example Add an atomic unset.
45
+ # document.add_atomic_unset(doc)
46
+ #
47
+ # @param [ Document ] document The child document.
48
+ #
49
+ # @return [ Array<Document> ] The children.
50
+ #
51
+ # @since 3.0.0
52
+ def add_atomic_unset(document)
53
+ document.flagged_for_destroy = true
54
+ (delayed_atomic_unsets[document.metadata_name.to_s] ||= []).push(document)
40
55
  end
41
56
 
42
57
  # For array fields these are the pushes that need to happen.
@@ -99,12 +114,12 @@ module Mongoid #:nodoc:
99
114
  #
100
115
  # @since 2.1.0
101
116
  def atomic_updates
102
- Modifiers.new.tap do |mods|
103
- generate_atomic_updates(mods, self)
104
- _children.each do |child|
105
- generate_atomic_updates(mods, child)
106
- end
117
+ mods = Modifiers.new
118
+ generate_atomic_updates(mods, self)
119
+ _children.each do |child|
120
+ generate_atomic_updates(mods, child)
107
121
  end
122
+ mods
108
123
  end
109
124
  alias :_updates :atomic_updates
110
125
 
@@ -151,6 +166,16 @@ module Mongoid #:nodoc:
151
166
  atomic_paths.position
152
167
  end
153
168
 
169
+ # Returns path of the attribute for modification
170
+ #
171
+ # @example Get path of the attribute
172
+ # address.atomic_attribute_name(:city)
173
+ #
174
+ # @return [ String ] The path to the document attribute in the database
175
+ def atomic_attribute_name(name)
176
+ embedded? ? "#{atomic_position}.#{name}" : name
177
+ end
178
+
154
179
  # Get all the attributes that need to be pulled.
155
180
  #
156
181
  # @example Get the pulls.
@@ -164,9 +189,7 @@ module Mongoid #:nodoc:
164
189
  delayed_atomic_pulls.each_pair do |_, docs|
165
190
  path = nil
166
191
  ids = docs.map do |doc|
167
- path ||= doc.atomic_path
168
- doc.destroyed = true
169
- doc.flagged_for_destroy = false
192
+ path ||= doc.flag_as_destroyed
170
193
  doc.id
171
194
  end
172
195
  pulls[path] = { "_id" => { "$in" => ids }} and path = nil
@@ -218,7 +241,15 @@ module Mongoid #:nodoc:
218
241
  #
219
242
  # @since 2.2.0
220
243
  def atomic_unsets
221
- @atomic_unsets ||= []
244
+ unsets = []
245
+ delayed_atomic_unsets.each_pair do |name, docs|
246
+ path = nil
247
+ docs.each do |doc|
248
+ path ||= doc.flag_as_destroyed
249
+ end
250
+ unsets.push(path || name)
251
+ end
252
+ unsets
222
253
  end
223
254
 
224
255
  # Get all the atomic sets that have had their saves delayed.
@@ -245,6 +276,32 @@ module Mongoid #:nodoc:
245
276
  @delayed_atomic_pulls ||= {}
246
277
  end
247
278
 
279
+ # Get the delayed atomic unsets.
280
+ #
281
+ # @example Get the delayed atomic unsets.
282
+ # document.delayed_atomic_unsets
283
+ #
284
+ # @return [ Hash ] The atomic unsets
285
+ #
286
+ # @since 3.0.0
287
+ def delayed_atomic_unsets
288
+ @delayed_atomic_unsets ||= {}
289
+ end
290
+
291
+ # Flag the document as destroyed and return the atomic path.
292
+ #
293
+ # @example Flag destroyed and return path.
294
+ # document.flag_as_destroyed
295
+ #
296
+ # @return [ String ] The atomic path.
297
+ #
298
+ # @since 3.0.0
299
+ def flag_as_destroyed
300
+ self.destroyed = true
301
+ self.flagged_for_destroy = false
302
+ atomic_path
303
+ end
304
+
248
305
  private
249
306
 
250
307
  # Get the atomic paths utility for this document.
@@ -252,9 +309,6 @@ module Mongoid #:nodoc:
252
309
  # @example Get the atomic paths.
253
310
  # document.atomic_paths
254
311
  #
255
- # @todo: Durran: Should probably raise error for embedded docs w/o
256
- # metadata.
257
- #
258
312
  # @return [ Object ] The associated path.
259
313
  #
260
314
  # @since 2.1.0
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
- module Mongoid #:nodoc:
3
- module Attributes #:nodoc:
2
+ module Mongoid
3
+ module Attributes
4
4
 
5
5
  # This module contains the behavior for processing attributes.
6
6
  module Processing
@@ -11,19 +11,21 @@ module Mongoid #:nodoc:
11
11
  # put into the document's attributes.
12
12
  #
13
13
  # @example Process the attributes.
14
- # person.process(:title => "sir", :age => 40)
14
+ # person.process_attributes(:title => "sir", :age => 40)
15
15
  #
16
16
  # @param [ Hash ] attrs The attributes to set.
17
17
  # @param [ Symbol ] role A role for scoped mass assignment.
18
18
  # @param [ Boolean ] guard_protected_attributes False to skip mass assignment protection.
19
19
  #
20
20
  # @since 2.0.0.rc.7
21
- def process(attrs = nil, role = :default, guard_protected_attributes = true)
21
+ def process_attributes(attrs = nil, role = :default, guard_protected_attributes = true)
22
22
  attrs ||= {}
23
- attrs = sanitize_for_mass_assignment(attrs, role) if guard_protected_attributes
24
- attrs.each_pair do |key, value|
25
- next if pending_attribute?(key, value)
26
- process_attribute(key, value)
23
+ if !attrs.empty?
24
+ attrs = sanitize_for_mass_assignment(attrs, role) if guard_protected_attributes
25
+ attrs.each_pair do |key, value|
26
+ next if pending_attribute?(key, value)
27
+ process_attribute(key, value)
28
+ end
27
29
  end
28
30
  yield self if block_given?
29
31
  process_pending
@@ -50,7 +52,7 @@ module Mongoid #:nodoc:
50
52
  pending_relations[name] = value
51
53
  return true
52
54
  end
53
- if nested_attributes.include?("#{name}=")
55
+ if nested_attributes.has_key?(name)
54
56
  pending_nested[name] = value
55
57
  return true
56
58
  end
@@ -92,9 +94,11 @@ module Mongoid #:nodoc:
92
94
  #
93
95
  # @since 2.0.0.rc.7
94
96
  def process_attribute(name, value)
95
- if Mongoid.allow_dynamic_fields && !respond_to?("#{name}=")
97
+ responds = respond_to?("#{name}=")
98
+ if Mongoid.allow_dynamic_fields && !responds
96
99
  write_attribute(name, value)
97
100
  else
101
+ raise Errors::UnknownAttribute.new(self.class, name) unless responds
98
102
  send("#{name}=", value)
99
103
  end
100
104
  end
@@ -0,0 +1,56 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module Attributes
4
+
5
+ # This module defines behaviour for readonly attributes.
6
+ module Readonly
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ class_attribute :readonly_attributes
11
+ self.readonly_attributes = ::Set.new
12
+ end
13
+
14
+ # Are we able to write the attribute with the provided name?
15
+ #
16
+ # @example Can we write the attribute?
17
+ # model.attribute_writable?(:title)
18
+ #
19
+ # @param [ String, Symbol ] name The name of the field.
20
+ #
21
+ # @return [ true, false ] If the document is new, or if the field is not
22
+ # readonly.
23
+ #
24
+ # @since 3.0.0
25
+ def attribute_writable?(name)
26
+ new_record? || !readonly_attributes.include?(name.to_s)
27
+ end
28
+
29
+ module ClassMethods
30
+
31
+ # Defines an attribute as readonly. This will ensure that the value for
32
+ # the attribute is only set when the document is new or we are
33
+ # creating. In other cases, the field write will be ignored with the
34
+ # exception of #remove_attribute and #update_attribute, where an error
35
+ # will get raised.
36
+ #
37
+ # @example Flag fields as readonly.
38
+ # class Band
39
+ # include Mongoid::Document
40
+ # field :name, type: String
41
+ # field :genre, type: String
42
+ # attr_readonly :name, :genre
43
+ # end
44
+ #
45
+ # @param [ Array<Symbol> ] names The names of the fields.
46
+ #
47
+ # @since 3.0.0
48
+ def attr_readonly(*names)
49
+ names.each do |name|
50
+ readonly_attributes << name.to_s
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -1,13 +1,15 @@
1
1
  # encoding: utf-8
2
2
  require "mongoid/attributes/processing"
3
+ require "mongoid/attributes/readonly"
3
4
 
4
- module Mongoid #:nodoc:
5
+ module Mongoid
5
6
 
6
7
  # This module contains the logic for handling the internal attributes hash,
7
8
  # and how to get and set values.
8
9
  module Attributes
9
10
  extend ActiveSupport::Concern
10
11
  include Processing
12
+ include Readonly
11
13
 
12
14
  attr_reader :attributes
13
15
  alias :raw_attributes :attributes
@@ -24,9 +26,22 @@ module Mongoid #:nodoc:
24
26
  # @since 1.0.0
25
27
  def attribute_present?(name)
26
28
  attribute = read_attribute(name)
27
- ! attribute.blank? || attribute == false
29
+ !attribute.blank? || attribute == false
30
+ end
31
+
32
+ # Does the document have the provided attribute?
33
+ #
34
+ # @example Does the document have the attribute?
35
+ # model.has_attribute?(:name)
36
+ #
37
+ # @param [ String, Symbol ] name The name of the attribute.
38
+ #
39
+ # @return [ true, false ] If the key is present in the attributes.
40
+ #
41
+ # @since 3.0.0
42
+ def has_attribute?(name)
43
+ attributes.has_key?(name.to_s)
28
44
  end
29
- alias :has_attribute? :attribute_present?
30
45
 
31
46
  # Read a value from the document attributes. If the value does not exist
32
47
  # it will return nil.
@@ -55,11 +70,18 @@ module Mongoid #:nodoc:
55
70
  #
56
71
  # @param [ String, Symbol ] name The name of the attribute to remove.
57
72
  #
73
+ # @raise [ Errors::ReadonlyAttribute ] If the field cannot be removed due
74
+ # to being flagged as reaodnly.
75
+ #
58
76
  # @since 1.0.0
59
77
  def remove_attribute(name)
78
+ access = name.to_s
79
+ unless attribute_writable?(name)
80
+ raise Errors::ReadonlyAttribute.new(name, :nil)
81
+ end
60
82
  _assigning do
61
- access = name.to_s
62
83
  attribute_will_change!(access)
84
+ delayed_atomic_unsets[atomic_attribute_name(access)] = []
63
85
  attributes.delete(access)
64
86
  end
65
87
  end
@@ -74,11 +96,12 @@ module Mongoid #:nodoc:
74
96
  # @return [ true, false ] True if it does, false if not.
75
97
  #
76
98
  # @since 1.0.0
77
- def respond_to?(*args)
78
- (Mongoid.allow_dynamic_fields &&
99
+ def respond_to?(name, include_private = false)
100
+ super || (
101
+ Mongoid.allow_dynamic_fields &&
79
102
  attributes &&
80
- attributes.has_key?(args.first.to_s.reader)
81
- ) || super
103
+ attributes.has_key?(name.to_s.reader)
104
+ )
82
105
  end
83
106
 
84
107
  # Write a single attribute to the document attribute hash. This will
@@ -96,18 +119,20 @@ module Mongoid #:nodoc:
96
119
  #
97
120
  # @since 1.0.0
98
121
  def write_attribute(name, value)
99
- _assigning do
100
- access = name.to_s
101
- localized = fields[access].try(:localized?)
102
- typed_value_for(access, value).tap do |value|
103
- unless attributes[access] == value || attribute_changed?(access)
122
+ access = name.to_s
123
+ if attribute_writable?(access)
124
+ _assigning do
125
+ localized = fields[access].try(:localized?)
126
+ typed_value = typed_value_for(access, value)
127
+ unless attributes[access] == typed_value || attribute_changed?(access)
104
128
  attribute_will_change!(access)
105
129
  end
106
130
  if localized
107
- (attributes[access] ||= {}).merge!(value)
131
+ (attributes[access] ||= {}).merge!(typed_value)
108
132
  else
109
- attributes[access] = value
133
+ attributes[access] = typed_value
110
134
  end
135
+ typed_value
111
136
  end
112
137
  end
113
138
  end
@@ -130,9 +155,7 @@ module Mongoid #:nodoc:
130
155
  # @since 2.2.1
131
156
  def assign_attributes(attrs = nil, options = {})
132
157
  _assigning do
133
- process(attrs, options[:as] || :default, !options[:without_protection]) do |document|
134
- document.identify if new? && id.blank?
135
- end
158
+ process_attributes(attrs, options[:as] || :default, !options[:without_protection])
136
159
  end
137
160
  end
138
161
 
@@ -151,11 +174,47 @@ module Mongoid #:nodoc:
151
174
  #
152
175
  # @since 1.0.0
153
176
  def write_attributes(attrs = nil, guard_protected_attributes = true)
154
- assign_attributes(attrs, :without_protection => !guard_protected_attributes)
177
+ assign_attributes(attrs, without_protection: !guard_protected_attributes)
155
178
  end
156
179
  alias :attributes= :write_attributes
157
180
 
158
- protected
181
+ private
182
+
183
+ # Define a reader method for a dynamic attribute.
184
+ #
185
+ # @api private
186
+ #
187
+ # @example Define a reader method.
188
+ # model.define_dynamic_reader(:field)
189
+ #
190
+ # @param [ String ] name The name of the field.
191
+ #
192
+ # @since 3.0.0
193
+ def define_dynamic_reader(name)
194
+ class_eval <<-READER
195
+ def #{name}
196
+ read_attribute(#{name.inspect})
197
+ end
198
+ READER
199
+ end
200
+
201
+ # Define a writer method for a dynamic attribute.
202
+ #
203
+ # @api private
204
+ #
205
+ # @example Define a writer method.
206
+ # model.define_dynamic_writer(:field)
207
+ #
208
+ # @param [ String ] name The name of the field.
209
+ #
210
+ # @since 3.0.0
211
+ def define_dynamic_writer(name)
212
+ class_eval <<-WRITER
213
+ def #{name}=(value)
214
+ write_attribute(#{name.inspect}, value)
215
+ end
216
+ WRITER
217
+ end
159
218
 
160
219
  # Used for allowing accessor methods for dynamic attributes.
161
220
  #
@@ -165,9 +224,13 @@ module Mongoid #:nodoc:
165
224
  attr = name.to_s
166
225
  return super unless attributes.has_key?(attr.reader)
167
226
  if attr.writer?
168
- write_attribute(attr.reader, (args.size > 1) ? args : args.first)
227
+ getter = attr.reader
228
+ define_dynamic_writer(getter)
229
+ write_attribute(getter, args.first)
169
230
  else
170
- read_attribute(attr.reader)
231
+ getter = attr.reader
232
+ define_dynamic_reader(getter)
233
+ read_attribute(getter)
171
234
  end
172
235
  end
173
236
 
@@ -183,10 +246,10 @@ module Mongoid #:nodoc:
183
246
  #
184
247
  # @since 1.0.0
185
248
  def typed_value_for(key, value)
186
- fields.has_key?(key) ? fields[key].serialize(value) : value
249
+ fields.has_key?(key) ? fields[key].mongoize(value) : value
187
250
  end
188
251
 
189
- module ClassMethods #:nodoc:
252
+ module ClassMethods
190
253
 
191
254
  # Alias the provided name to the original field. This will provide an
192
255
  # aliased getter, setter, existance check, and all dirty attribute
@@ -205,14 +268,14 @@ module Mongoid #:nodoc:
205
268
  # @since 2.3.0
206
269
  def alias_attribute(name, original)
207
270
  class_eval <<-RUBY
208
- alias :#{name} :#{original}
209
- alias :#{name}= :#{original}=
210
- alias :#{name}? :#{original}?
211
- alias :#{name}_change :#{original}_change
212
- alias :#{name}_changed? :#{original}_changed?
213
- alias :reset_#{name}! :reset_#{original}!
214
- alias :#{name}_was :#{original}_was
215
- alias :#{name}_will_change! :#{original}_will_change!
271
+ alias #{name} #{original}
272
+ alias #{name}= #{original}=
273
+ alias #{name}? #{original}?
274
+ alias #{name}_change #{original}_change
275
+ alias #{name}_changed? #{original}_changed?
276
+ alias reset_#{name}! reset_#{original}!
277
+ alias #{name}_was #{original}_was
278
+ alias #{name}_will_change! #{original}_will_change!
216
279
  RUBY
217
280
  end
218
281
  end