mongoid 2.4.9 → 3.0.0.rc

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 (351) hide show
  1. data/CHANGELOG.md +869 -8
  2. data/LICENSE +1 -1
  3. data/README.md +10 -11
  4. data/Rakefile +2 -17
  5. data/lib/config/locales/en.yml +441 -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 +16 -6
  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 +100 -42
  16. data/lib/mongoid/collections/retry.rb +2 -3
  17. data/lib/mongoid/components.rb +10 -22
  18. data/lib/mongoid/config/environment.rb +4 -3
  19. data/lib/mongoid/config/inflections.rb +6 -0
  20. data/lib/mongoid/config/options.rb +1 -1
  21. data/lib/mongoid/config/validators/option.rb +25 -0
  22. data/lib/mongoid/config/validators/session.rb +140 -0
  23. data/lib/mongoid/config/validators.rb +3 -0
  24. data/lib/mongoid/config.rb +87 -233
  25. data/lib/mongoid/contextual/aggregable/memory.rb +98 -0
  26. data/lib/mongoid/contextual/aggregable/mongo.rb +181 -0
  27. data/lib/mongoid/contextual/atomic.rb +179 -0
  28. data/lib/mongoid/contextual/command.rb +43 -0
  29. data/lib/mongoid/contextual/find_and_modify.rb +66 -0
  30. data/lib/mongoid/contextual/map_reduce.rb +273 -0
  31. data/lib/mongoid/contextual/memory.rb +383 -0
  32. data/lib/mongoid/contextual/mongo.rb +543 -0
  33. data/lib/mongoid/contextual.rb +50 -0
  34. data/lib/mongoid/copyable.rb +2 -2
  35. data/lib/mongoid/criteria.rb +436 -248
  36. data/lib/mongoid/criterion/inspection.rb +14 -8
  37. data/lib/mongoid/criterion/scoping.rb +114 -44
  38. data/lib/mongoid/dirty.rb +152 -67
  39. data/lib/mongoid/document.rb +68 -49
  40. data/lib/mongoid/errors/ambiguous_relationship.rb +51 -0
  41. data/lib/mongoid/errors/callback.rb +5 -6
  42. data/lib/mongoid/errors/delete_restriction.rb +29 -0
  43. data/lib/mongoid/errors/document_not_found.rb +98 -17
  44. data/lib/mongoid/errors/eager_load.rb +3 -6
  45. data/lib/mongoid/errors/invalid_collection.rb +3 -3
  46. data/lib/mongoid/errors/invalid_config_option.rb +27 -0
  47. data/lib/mongoid/errors/invalid_database.rb +3 -3
  48. data/lib/mongoid/errors/invalid_field.rb +54 -8
  49. data/lib/mongoid/errors/invalid_field_option.rb +35 -0
  50. data/lib/mongoid/errors/invalid_find.rb +3 -3
  51. data/lib/mongoid/errors/invalid_index.rb +28 -0
  52. data/lib/mongoid/errors/invalid_options.rb +4 -4
  53. data/lib/mongoid/errors/invalid_scope.rb +24 -0
  54. data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +38 -0
  55. data/lib/mongoid/errors/invalid_storage_options.rb +27 -0
  56. data/lib/mongoid/errors/invalid_time.rb +3 -6
  57. data/lib/mongoid/errors/inverse_not_found.rb +29 -0
  58. data/lib/mongoid/errors/mixed_relations.rb +4 -9
  59. data/lib/mongoid/errors/mixed_session_configuration.rb +28 -0
  60. data/lib/mongoid/errors/mongoid_error.rb +54 -3
  61. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +28 -0
  62. data/lib/mongoid/errors/no_default_session.rb +23 -0
  63. data/lib/mongoid/errors/no_environment.rb +3 -3
  64. data/lib/mongoid/errors/no_map_reduce_output.rb +24 -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 +22 -1
  80. data/lib/mongoid/extensions/array.rb +127 -0
  81. data/lib/mongoid/extensions/big_decimal.rb +42 -0
  82. data/lib/mongoid/extensions/boolean.rb +24 -0
  83. data/lib/mongoid/extensions/date.rb +70 -0
  84. data/lib/mongoid/extensions/date_time.rb +68 -0
  85. data/lib/mongoid/extensions/false_class.rb +26 -0
  86. data/lib/mongoid/extensions/float.rb +44 -0
  87. data/lib/mongoid/extensions/hash.rb +91 -0
  88. data/lib/mongoid/extensions/integer.rb +54 -0
  89. data/lib/mongoid/extensions/module.rb +28 -0
  90. data/lib/mongoid/extensions/nil_class.rb +21 -0
  91. data/lib/mongoid/extensions/object.rb +188 -0
  92. data/lib/mongoid/extensions/object_id.rb +53 -0
  93. data/lib/mongoid/extensions/range.rb +55 -0
  94. data/lib/mongoid/extensions/regexp.rb +27 -0
  95. data/lib/mongoid/extensions/set.rb +55 -0
  96. data/lib/mongoid/extensions/string.rb +155 -0
  97. data/lib/mongoid/extensions/symbol.rb +54 -0
  98. data/lib/mongoid/extensions/time.rb +78 -0
  99. data/lib/mongoid/extensions/time_with_zone.rb +55 -0
  100. data/lib/mongoid/extensions/true_class.rb +26 -0
  101. data/lib/mongoid/extensions.rb +28 -76
  102. data/lib/mongoid/factory.rb +4 -4
  103. data/lib/mongoid/fields/foreign_key.rb +134 -0
  104. data/lib/mongoid/fields/localized.rb +73 -0
  105. data/lib/mongoid/fields/standard.rb +268 -0
  106. data/lib/mongoid/fields/validators/macro.rb +83 -0
  107. data/lib/mongoid/fields/validators.rb +2 -0
  108. data/lib/mongoid/fields.rb +129 -194
  109. data/lib/mongoid/finders.rb +42 -43
  110. data/lib/mongoid/hierarchy.rb +25 -14
  111. data/lib/mongoid/identity_map.rb +39 -12
  112. data/lib/mongoid/indexes/validators/options.rb +80 -0
  113. data/lib/mongoid/indexes.rb +66 -15
  114. data/lib/mongoid/inspection.rb +1 -1
  115. data/lib/mongoid/javascript.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 +8 -10
  134. data/lib/mongoid/nested_attributes.rb +17 -9
  135. data/lib/mongoid/observer.rb +1 -2
  136. data/lib/mongoid/paranoia.rb +13 -18
  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.rb +6 -19
  159. data/lib/mongoid/persistence.rb +64 -27
  160. data/lib/mongoid/railtie.rb +26 -11
  161. data/lib/mongoid/railties/database.rake +22 -108
  162. data/lib/mongoid/relations/accessors.rb +119 -19
  163. data/lib/mongoid/relations/auto_save.rb +59 -5
  164. data/lib/mongoid/relations/binding.rb +211 -2
  165. data/lib/mongoid/relations/bindings/embedded/in.rb +16 -22
  166. data/lib/mongoid/relations/bindings/embedded/many.rb +9 -50
  167. data/lib/mongoid/relations/bindings/embedded/one.rb +10 -16
  168. data/lib/mongoid/relations/bindings/referenced/in.rb +31 -57
  169. data/lib/mongoid/relations/bindings/referenced/many.rb +8 -20
  170. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +15 -19
  171. data/lib/mongoid/relations/bindings/referenced/one.rb +10 -24
  172. data/lib/mongoid/relations/builder.rb +3 -3
  173. data/lib/mongoid/relations/builders/embedded/in.rb +5 -5
  174. data/lib/mongoid/relations/builders/embedded/many.rb +12 -12
  175. data/lib/mongoid/relations/builders/embedded/one.rb +6 -6
  176. data/lib/mongoid/relations/builders/nested_attributes/many.rb +8 -8
  177. data/lib/mongoid/relations/builders/nested_attributes/one.rb +4 -4
  178. data/lib/mongoid/relations/builders/referenced/in.rb +4 -4
  179. data/lib/mongoid/relations/builders/referenced/many.rb +5 -5
  180. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +7 -5
  181. data/lib/mongoid/relations/builders/referenced/one.rb +5 -5
  182. data/lib/mongoid/relations/builders.rb +19 -16
  183. data/lib/mongoid/relations/cascading/delete.rb +12 -4
  184. data/lib/mongoid/relations/cascading/destroy.rb +3 -3
  185. data/lib/mongoid/relations/cascading/nullify.rb +3 -3
  186. data/lib/mongoid/relations/cascading/restrict.rb +37 -0
  187. data/lib/mongoid/relations/cascading.rb +6 -4
  188. data/lib/mongoid/relations/constraint.rb +4 -3
  189. data/lib/mongoid/relations/conversions.rb +5 -6
  190. data/lib/mongoid/relations/cyclic.rb +7 -7
  191. data/lib/mongoid/relations/embedded/batchable.rb +346 -0
  192. data/lib/mongoid/relations/embedded/in.rb +23 -12
  193. data/lib/mongoid/relations/embedded/many.rb +99 -148
  194. data/lib/mongoid/relations/embedded/one.rb +25 -14
  195. data/lib/mongoid/relations/macros.rb +105 -60
  196. data/lib/mongoid/relations/many.rb +93 -14
  197. data/lib/mongoid/relations/metadata.rb +231 -45
  198. data/lib/mongoid/relations/nested_builder.rb +3 -5
  199. data/lib/mongoid/relations/one.rb +14 -2
  200. data/lib/mongoid/relations/options.rb +2 -2
  201. data/lib/mongoid/relations/polymorphic.rb +9 -9
  202. data/lib/mongoid/relations/proxy.rb +60 -31
  203. data/lib/mongoid/relations/referenced/in.rb +40 -15
  204. data/lib/mongoid/relations/referenced/many.rb +116 -122
  205. data/lib/mongoid/relations/referenced/many_to_many.rb +101 -46
  206. data/lib/mongoid/relations/referenced/one.rb +34 -13
  207. data/lib/mongoid/relations/reflections.rb +3 -3
  208. data/lib/mongoid/relations/synchronization.rb +19 -23
  209. data/lib/mongoid/relations/targets/enumerable.rb +86 -57
  210. data/lib/mongoid/relations/touchable.rb +32 -0
  211. data/lib/mongoid/relations.rb +6 -6
  212. data/lib/mongoid/reloading.rb +12 -14
  213. data/lib/mongoid/scoping.rb +329 -0
  214. data/lib/mongoid/serialization.rb +13 -30
  215. data/lib/mongoid/sessions/factory.rb +106 -0
  216. data/lib/mongoid/sessions/mongo_uri.rb +93 -0
  217. data/lib/mongoid/sessions/validators/storage.rb +49 -0
  218. data/lib/mongoid/sessions/validators.rb +2 -0
  219. data/lib/mongoid/sessions.rb +359 -0
  220. data/lib/mongoid/sharding.rb +6 -6
  221. data/lib/mongoid/state.rb +6 -7
  222. data/lib/mongoid/threaded/lifecycle.rb +21 -21
  223. data/lib/mongoid/threaded/sessions.rb +0 -0
  224. data/lib/mongoid/threaded.rb +167 -59
  225. data/lib/mongoid/timestamps/created.rb +8 -4
  226. data/lib/mongoid/timestamps/timeless.rb +6 -4
  227. data/lib/mongoid/timestamps/updated.rb +3 -3
  228. data/lib/mongoid/timestamps.rb +1 -1
  229. data/lib/mongoid/unit_of_work.rb +61 -0
  230. data/lib/mongoid/validations/associated.rb +2 -2
  231. data/lib/mongoid/validations/format.rb +2 -2
  232. data/lib/mongoid/validations/presence.rb +34 -4
  233. data/lib/mongoid/validations/uniqueness.rb +103 -25
  234. data/lib/mongoid/validations.rb +62 -20
  235. data/lib/mongoid/version.rb +2 -2
  236. data/lib/mongoid/versioning.rb +25 -26
  237. data/lib/mongoid.rb +24 -39
  238. data/lib/rack/mongoid/middleware/identity_map.rb +3 -3
  239. data/lib/rails/generators/mongoid/config/config_generator.rb +1 -1
  240. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +59 -19
  241. data/lib/rails/generators/mongoid/model/model_generator.rb +7 -7
  242. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +2 -2
  243. data/lib/rails/generators/mongoid/observer/observer_generator.rb +4 -4
  244. data/lib/rails/generators/mongoid_generator.rb +5 -5
  245. data/lib/rails/mongoid.rb +69 -25
  246. metadata +93 -155
  247. data/lib/config/locales/bg.yml +0 -61
  248. data/lib/config/locales/de.yml +0 -61
  249. data/lib/config/locales/en-GB.yml +0 -64
  250. data/lib/config/locales/es.yml +0 -59
  251. data/lib/config/locales/fr.yml +0 -62
  252. data/lib/config/locales/hi.yml +0 -53
  253. data/lib/config/locales/hu.yml +0 -64
  254. data/lib/config/locales/id.yml +0 -62
  255. data/lib/config/locales/it.yml +0 -59
  256. data/lib/config/locales/ja.yml +0 -57
  257. data/lib/config/locales/kr.yml +0 -54
  258. data/lib/config/locales/nl.yml +0 -61
  259. data/lib/config/locales/pl.yml +0 -59
  260. data/lib/config/locales/pt-BR.yml +0 -60
  261. data/lib/config/locales/pt.yml +0 -60
  262. data/lib/config/locales/ro.yml +0 -66
  263. data/lib/config/locales/ru.yml +0 -61
  264. data/lib/config/locales/sv.yml +0 -60
  265. data/lib/config/locales/vi.yml +0 -62
  266. data/lib/config/locales/zh-CN.yml +0 -53
  267. data/lib/mongoid/collection.rb +0 -157
  268. data/lib/mongoid/collections/master.rb +0 -45
  269. data/lib/mongoid/collections/operations.rb +0 -44
  270. data/lib/mongoid/collections.rb +0 -120
  271. data/lib/mongoid/config/database.rb +0 -181
  272. data/lib/mongoid/config/replset_database.rb +0 -80
  273. data/lib/mongoid/contexts/enumerable/sort.rb +0 -43
  274. data/lib/mongoid/contexts/enumerable.rb +0 -313
  275. data/lib/mongoid/contexts/mongo.rb +0 -485
  276. data/lib/mongoid/contexts.rb +0 -25
  277. data/lib/mongoid/criterion/builder.rb +0 -34
  278. data/lib/mongoid/criterion/complex.rb +0 -84
  279. data/lib/mongoid/criterion/creational.rb +0 -34
  280. data/lib/mongoid/criterion/exclusion.rb +0 -108
  281. data/lib/mongoid/criterion/inclusion.rb +0 -290
  282. data/lib/mongoid/criterion/optional.rb +0 -259
  283. data/lib/mongoid/criterion/selector.rb +0 -177
  284. data/lib/mongoid/cursor.rb +0 -88
  285. data/lib/mongoid/default_scope.rb +0 -36
  286. data/lib/mongoid/errors/invalid_type.rb +0 -25
  287. data/lib/mongoid/extensions/array/deep_copy.rb +0 -25
  288. data/lib/mongoid/extensions/array/deletion.rb +0 -29
  289. data/lib/mongoid/extensions/false_class/equality.rb +0 -26
  290. data/lib/mongoid/extensions/hash/criteria_helpers.rb +0 -47
  291. data/lib/mongoid/extensions/hash/deep_copy.rb +0 -25
  292. data/lib/mongoid/extensions/hash/scoping.rb +0 -25
  293. data/lib/mongoid/extensions/integer/checks.rb +0 -23
  294. data/lib/mongoid/extensions/nil/collectionization.rb +0 -23
  295. data/lib/mongoid/extensions/object/checks.rb +0 -29
  296. data/lib/mongoid/extensions/object/deep_copy.rb +0 -21
  297. data/lib/mongoid/extensions/object/reflections.rb +0 -48
  298. data/lib/mongoid/extensions/object/substitutable.rb +0 -15
  299. data/lib/mongoid/extensions/object/yoda.rb +0 -44
  300. data/lib/mongoid/extensions/object_id/conversions.rb +0 -60
  301. data/lib/mongoid/extensions/proc/scoping.rb +0 -25
  302. data/lib/mongoid/extensions/string/checks.rb +0 -36
  303. data/lib/mongoid/extensions/string/conversions.rb +0 -22
  304. data/lib/mongoid/extensions/string/inflections.rb +0 -118
  305. data/lib/mongoid/extensions/symbol/checks.rb +0 -23
  306. data/lib/mongoid/extensions/symbol/inflections.rb +0 -67
  307. data/lib/mongoid/extensions/true_class/equality.rb +0 -26
  308. data/lib/mongoid/extras.rb +0 -31
  309. data/lib/mongoid/fields/internal/array.rb +0 -76
  310. data/lib/mongoid/fields/internal/big_decimal.rb +0 -63
  311. data/lib/mongoid/fields/internal/bignum.rb +0 -10
  312. data/lib/mongoid/fields/internal/binary.rb +0 -11
  313. data/lib/mongoid/fields/internal/boolean.rb +0 -58
  314. data/lib/mongoid/fields/internal/date.rb +0 -51
  315. data/lib/mongoid/fields/internal/date_time.rb +0 -28
  316. data/lib/mongoid/fields/internal/false_class.rb +0 -10
  317. data/lib/mongoid/fields/internal/fixnum.rb +0 -10
  318. data/lib/mongoid/fields/internal/float.rb +0 -47
  319. data/lib/mongoid/fields/internal/foreign_keys/array.rb +0 -88
  320. data/lib/mongoid/fields/internal/foreign_keys/object.rb +0 -56
  321. data/lib/mongoid/fields/internal/hash.rb +0 -11
  322. data/lib/mongoid/fields/internal/integer.rb +0 -59
  323. data/lib/mongoid/fields/internal/localized.rb +0 -62
  324. data/lib/mongoid/fields/internal/nil_class.rb +0 -53
  325. data/lib/mongoid/fields/internal/object.rb +0 -11
  326. data/lib/mongoid/fields/internal/object_id.rb +0 -46
  327. data/lib/mongoid/fields/internal/range.rb +0 -61
  328. data/lib/mongoid/fields/internal/set.rb +0 -57
  329. data/lib/mongoid/fields/internal/string.rb +0 -42
  330. data/lib/mongoid/fields/internal/symbol.rb +0 -43
  331. data/lib/mongoid/fields/internal/time.rb +0 -23
  332. data/lib/mongoid/fields/internal/time_with_zone.rb +0 -23
  333. data/lib/mongoid/fields/internal/timekeeping.rb +0 -122
  334. data/lib/mongoid/fields/internal/true_class.rb +0 -10
  335. data/lib/mongoid/fields/mappings.rb +0 -42
  336. data/lib/mongoid/fields/serializable.rb +0 -270
  337. data/lib/mongoid/identity.rb +0 -92
  338. data/lib/mongoid/keys.rb +0 -144
  339. data/lib/mongoid/logger.rb +0 -45
  340. data/lib/mongoid/multi_database.rb +0 -31
  341. data/lib/mongoid/named_scope.rb +0 -166
  342. data/lib/mongoid/relations/embedded/atomic/operation.rb +0 -63
  343. data/lib/mongoid/relations/embedded/atomic/pull.rb +0 -65
  344. data/lib/mongoid/relations/embedded/atomic/push_all.rb +0 -59
  345. data/lib/mongoid/relations/embedded/atomic/set.rb +0 -61
  346. data/lib/mongoid/relations/embedded/atomic/unset.rb +0 -41
  347. data/lib/mongoid/relations/embedded/atomic.rb +0 -89
  348. data/lib/mongoid/relations/referenced/batch/insert.rb +0 -57
  349. data/lib/mongoid/relations/referenced/batch.rb +0 -73
  350. data/lib/mongoid/safety.rb +0 -105
  351. data/lib/mongoid/scope.rb +0 -31
@@ -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.
@@ -99,12 +99,12 @@ module Mongoid #:nodoc:
99
99
  #
100
100
  # @since 2.1.0
101
101
  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
102
+ mods = Modifiers.new
103
+ generate_atomic_updates(mods, self)
104
+ _children.each do |child|
105
+ generate_atomic_updates(mods, child)
107
106
  end
107
+ mods
108
108
  end
109
109
  alias :_updates :atomic_updates
110
110
 
@@ -151,6 +151,16 @@ module Mongoid #:nodoc:
151
151
  atomic_paths.position
152
152
  end
153
153
 
154
+ # Returns path of the attribute for modification
155
+ #
156
+ # @example Get path of the attribute
157
+ # address.atomic_attribute_name(:city)
158
+ #
159
+ # @return [ String ] The path to the document attribute in the database
160
+ def atomic_attribute_name(name)
161
+ embedded? ? "#{atomic_position}.#{name}" : name
162
+ end
163
+
154
164
  # Get all the attributes that need to be pulled.
155
165
  #
156
166
  # @example Get the pulls.
@@ -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.any?
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
+ atomic_unsets.push(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
@@ -1,28 +1,76 @@
1
1
  # encoding: utf-8
2
- module Mongoid #:nodoc:
2
+ module Mongoid
3
3
 
4
4
  # This module contains all the callback hooks for Mongoid.
5
5
  module Callbacks
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  CALLBACKS = [
9
- :before_validation, :after_validation,
10
- :after_initialize, :after_build,
11
- :before_create, :around_create, :after_create,
12
- :before_destroy, :around_destroy, :after_destroy,
13
- :before_save, :around_save, :after_save,
14
- :before_update, :around_update, :after_update,
9
+ :after_build,
10
+ :after_create,
11
+ :after_destroy,
12
+ :after_initialize,
13
+ :after_save,
14
+ :after_update,
15
+ :after_validation,
16
+ :around_create,
17
+ :around_destroy,
18
+ :around_save,
19
+ :around_update,
20
+ :before_create,
21
+ :before_destroy,
22
+ :before_save,
23
+ :before_update,
24
+ :before_validation
15
25
  ]
16
26
 
17
27
  included do
18
28
  extend ActiveModel::Callbacks
19
29
  include ActiveModel::Validations::Callbacks
20
30
 
21
- define_model_callbacks :initialize, :only => :after
22
- define_model_callbacks :build, :only => :after
31
+ define_model_callbacks :initialize, only: :after
32
+ define_model_callbacks :build, only: :after
23
33
  define_model_callbacks :create, :destroy, :save, :update
24
34
  end
25
35
 
36
+ # Run only the after callbacks for the specific event.
37
+ #
38
+ # @note ActiveSupport does not allow this type of behaviour by default, so
39
+ # Mongoid has to get around it and implement itself.
40
+ #
41
+ # @example Run only the after save callbacks.
42
+ # model.run_after_callbacks(:save)
43
+ #
44
+ # @param [ Array<Symbol> ] kinds The events that are occurring.
45
+ #
46
+ # @return [ Object ] The result of the chain executing.
47
+ #
48
+ # @since 3.0.0
49
+ def run_after_callbacks(*kinds)
50
+ kinds.each do |kind|
51
+ run_targeted_callbacks(:after, kind)
52
+ end
53
+ end
54
+
55
+ # Run only the before callbacks for the specific event.
56
+ #
57
+ # @note ActiveSupport does not allow this type of behaviour by default, so
58
+ # Mongoid has to get around it and implement itself.
59
+ #
60
+ # @example Run only the before save callbacks.
61
+ # model.run_before_callbacks(:save, :create)
62
+ #
63
+ # @param [ Array<Symbol> ] kinds The events that are occurring.
64
+ #
65
+ # @return [ Object ] The result of the chain executing.
66
+ #
67
+ # @since 3.0.0
68
+ def run_before_callbacks(*kinds)
69
+ kinds.each do |kind|
70
+ run_targeted_callbacks(:before, kind)
71
+ end
72
+ end
73
+
26
74
  # Run the callbacks for the document. This overrides active support's
27
75
  # functionality to cascade callbacks to embedded documents that have been
28
76
  # flagged as such.
@@ -39,35 +87,16 @@ module Mongoid #:nodoc:
39
87
  #
40
88
  # @since 2.3.0
41
89
  def run_callbacks(kind, *args, &block)
42
- run_cascading_callbacks(cascadable_children(kind), kind, *args) {}
90
+ cascadable_children(kind).each do |child|
91
+ unless child.run_callbacks(child_callback_type(kind, child), *args)
92
+ return false
93
+ end
94
+ end
43
95
  super(kind, *args, &block)
44
96
  end
45
97
 
46
98
  private
47
99
 
48
- # Execute the callbacks, including all children that have cascade callbacks
49
- # set to true.
50
- #
51
- # @example Run the cascading callbacks.
52
- # document.run_cascading_callbacks([], :update)
53
- #
54
- # @param [ Array<Document> ] children The cascading children.
55
- # @param [ Symbol ] kind The callback type.
56
- # @param [ Array ] args The options.
57
- #
58
- # @since 2.3.0
59
- def run_cascading_callbacks(children, kind, *args, &block)
60
- if child = children.pop
61
- run_cascading_callbacks(children, kind, *args) do
62
- child.run_callbacks(child_callback_type(kind, child), *args) do
63
- block.call
64
- end
65
- end
66
- else
67
- block.call
68
- end
69
- end
70
-
71
100
  # Get all the child embedded documents that are flagged as cascadable.
72
101
  #
73
102
  # @example Get all the cascading children.
@@ -78,19 +107,21 @@ module Mongoid #:nodoc:
78
107
  # @return [ Array<Document> ] The children.
79
108
  #
80
109
  # @since 2.3.0
81
- def cascadable_children(kind)
82
- [].tap do |children|
83
- relations.each_pair do |name, metadata|
84
- next unless metadata.cascading_callbacks?
110
+ def cascadable_children(kind, children = Set.new)
111
+ embedded_relations.each_pair do |name, metadata|
112
+ next unless metadata.cascading_callbacks?
113
+ without_autobuild do
85
114
  delayed_pulls = delayed_atomic_pulls[name]
86
- children.concat(delayed_pulls) if delayed_pulls
87
- child = send(name)
88
- Array.wrap(child).each do |doc|
89
- children.push(doc) if cascadable_child?(kind, doc)
90
- children.concat(doc.send(:cascadable_children, kind))
115
+ children.merge(delayed_pulls) if delayed_pulls
116
+ relation = send(name)
117
+ Array.wrap(relation).each do |child|
118
+ next if children.include?(child)
119
+ children.add(child) if cascadable_child?(kind, child)
120
+ children.merge(child.send(:cascadable_children, kind, children))
91
121
  end
92
122
  end
93
123
  end
124
+ children.to_a
94
125
  end
95
126
 
96
127
  # Determine if the child should fire the callback.
@@ -132,5 +163,32 @@ module Mongoid #:nodoc:
132
163
  kind
133
164
  end
134
165
  end
166
+
167
+ # Run only the callbacks for the target location (before, after, around)
168
+ # and kind (save, update, create).
169
+ #
170
+ # @example Run the targeted callbacks.
171
+ # model.run_targeted_callbacks(:before, :save)
172
+ #
173
+ # @param [ Symbol ] place The time to run, :before, :after, :around.
174
+ # @param [ Symbol ] kind The type of callback, :save, :create, :update.
175
+ #
176
+ # @return [ Object ] The result of the chain execution.
177
+ #
178
+ # @since 3.0.0
179
+ def run_targeted_callbacks(place, kind)
180
+ name = "_run__#{place}__#{kind}__callbacks"
181
+ unless respond_to?(name)
182
+ chain = ActiveSupport::Callbacks::CallbackChain.new(name, {})
183
+ send("_#{kind}_callbacks").each do |callback|
184
+ chain.push(callback) if callback.kind == place
185
+ end
186
+ class_eval <<-EOM
187
+ def #{name}() #{chain.compile} end
188
+ protected :#{name}
189
+ EOM
190
+ end
191
+ send(name)
192
+ end
135
193
  end
136
194
  end
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
- module Mongoid #:nodoc:
3
- module Collections #:nodoc:
2
+ module Mongoid
3
+ module Collections
4
4
 
5
5
  # Provides behaviour for retrying commands on connection failure.
6
6
  module Retry
@@ -32,7 +32,6 @@ module Mongoid #:nodoc:
32
32
  retry
33
33
  rescue Mongo::OperationFailure => ex
34
34
  if ex.message =~ /not master/
35
- Mongoid.reconnect!
36
35
  retries = increase_retry_attempts(retries, ex)
37
36
  retry
38
37
  else