mongoid 2.8.1 → 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 +802 -58
  2. data/LICENSE +1 -1
  3. data/README.md +10 -11
  4. data/Rakefile +2 -8
  5. data/lib/config/locales/en.yml +441 -51
  6. data/lib/mongoid.rb +24 -39
  7. data/lib/mongoid/atomic.rb +16 -33
  8. data/lib/mongoid/atomic/modifiers.rb +2 -2
  9. data/lib/mongoid/atomic/paths/embedded.rb +4 -5
  10. data/lib/mongoid/atomic/paths/embedded/many.rb +6 -6
  11. data/lib/mongoid/atomic/paths/embedded/one.rb +5 -5
  12. data/lib/mongoid/atomic/paths/root.rb +4 -5
  13. data/lib/mongoid/attributes.rb +95 -32
  14. data/lib/mongoid/attributes/processing.rb +14 -10
  15. data/lib/mongoid/attributes/readonly.rb +56 -0
  16. data/lib/mongoid/callbacks.rb +90 -27
  17. data/lib/mongoid/collections/retry.rb +2 -3
  18. data/lib/mongoid/components.rb +11 -23
  19. data/lib/mongoid/config.rb +87 -233
  20. data/lib/mongoid/config/environment.rb +5 -6
  21. data/lib/mongoid/config/inflections.rb +6 -0
  22. data/lib/mongoid/config/options.rb +1 -1
  23. data/lib/mongoid/config/validators.rb +3 -0
  24. data/lib/mongoid/config/validators/option.rb +25 -0
  25. data/lib/mongoid/config/validators/session.rb +140 -0
  26. data/lib/mongoid/contextual.rb +50 -0
  27. data/lib/mongoid/contextual/aggregable/memory.rb +98 -0
  28. data/lib/mongoid/contextual/aggregable/mongo.rb +181 -0
  29. data/lib/mongoid/contextual/atomic.rb +179 -0
  30. data/lib/mongoid/contextual/command.rb +43 -0
  31. data/lib/mongoid/contextual/find_and_modify.rb +66 -0
  32. data/lib/mongoid/contextual/map_reduce.rb +273 -0
  33. data/lib/mongoid/contextual/memory.rb +383 -0
  34. data/lib/mongoid/contextual/mongo.rb +543 -0
  35. data/lib/mongoid/copyable.rb +3 -34
  36. data/lib/mongoid/criteria.rb +436 -250
  37. data/lib/mongoid/criterion/inspection.rb +14 -8
  38. data/lib/mongoid/criterion/scoping.rb +114 -44
  39. data/lib/mongoid/dirty.rb +152 -67
  40. data/lib/mongoid/document.rb +69 -50
  41. data/lib/mongoid/errors.rb +22 -1
  42. data/lib/mongoid/errors/ambiguous_relationship.rb +51 -0
  43. data/lib/mongoid/errors/callback.rb +5 -6
  44. data/lib/mongoid/errors/delete_restriction.rb +29 -0
  45. data/lib/mongoid/errors/document_not_found.rb +98 -17
  46. data/lib/mongoid/errors/eager_load.rb +3 -6
  47. data/lib/mongoid/errors/invalid_collection.rb +3 -3
  48. data/lib/mongoid/errors/invalid_config_option.rb +27 -0
  49. data/lib/mongoid/errors/invalid_database.rb +3 -3
  50. data/lib/mongoid/errors/invalid_field.rb +54 -8
  51. data/lib/mongoid/errors/invalid_field_option.rb +35 -0
  52. data/lib/mongoid/errors/invalid_find.rb +3 -3
  53. data/lib/mongoid/errors/invalid_index.rb +28 -0
  54. data/lib/mongoid/errors/invalid_options.rb +4 -4
  55. data/lib/mongoid/errors/invalid_scope.rb +24 -0
  56. data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +38 -0
  57. data/lib/mongoid/errors/invalid_storage_options.rb +27 -0
  58. data/lib/mongoid/errors/invalid_time.rb +3 -6
  59. data/lib/mongoid/errors/inverse_not_found.rb +29 -0
  60. data/lib/mongoid/errors/mixed_relations.rb +4 -9
  61. data/lib/mongoid/errors/mixed_session_configuration.rb +28 -0
  62. data/lib/mongoid/errors/mongoid_error.rb +54 -3
  63. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +28 -0
  64. data/lib/mongoid/errors/no_default_session.rb +23 -0
  65. data/lib/mongoid/errors/no_environment.rb +3 -3
  66. data/lib/mongoid/errors/no_map_reduce_output.rb +24 -0
  67. data/lib/mongoid/errors/no_parent.rb +24 -0
  68. data/lib/mongoid/errors/no_session_config.rb +22 -0
  69. data/lib/mongoid/errors/no_session_database.rb +27 -0
  70. data/lib/mongoid/errors/no_session_hosts.rb +27 -0
  71. data/lib/mongoid/errors/no_sessions_config.rb +20 -0
  72. data/lib/mongoid/errors/readonly_attribute.rb +25 -0
  73. data/lib/mongoid/errors/scope_overwrite.rb +4 -4
  74. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +4 -4
  75. data/lib/mongoid/errors/unknown_attribute.rb +25 -0
  76. data/lib/mongoid/errors/unsaved_document.rb +4 -8
  77. data/lib/mongoid/errors/unsupported_javascript.rb +27 -0
  78. data/lib/mongoid/errors/unsupported_version.rb +4 -4
  79. data/lib/mongoid/errors/validations.rb +7 -6
  80. data/lib/mongoid/errors/versioning_not_on_root.rb +23 -0
  81. data/lib/mongoid/extensions.rb +28 -76
  82. data/lib/mongoid/extensions/array.rb +127 -0
  83. data/lib/mongoid/extensions/big_decimal.rb +42 -0
  84. data/lib/mongoid/extensions/boolean.rb +24 -0
  85. data/lib/mongoid/extensions/date.rb +70 -0
  86. data/lib/mongoid/extensions/date_time.rb +68 -0
  87. data/lib/mongoid/extensions/false_class.rb +26 -0
  88. data/lib/mongoid/extensions/float.rb +44 -0
  89. data/lib/mongoid/extensions/hash.rb +91 -0
  90. data/lib/mongoid/extensions/integer.rb +54 -0
  91. data/lib/mongoid/extensions/module.rb +28 -0
  92. data/lib/mongoid/extensions/nil_class.rb +21 -0
  93. data/lib/mongoid/extensions/object.rb +188 -0
  94. data/lib/mongoid/extensions/object_id.rb +53 -0
  95. data/lib/mongoid/extensions/range.rb +55 -0
  96. data/lib/mongoid/extensions/regexp.rb +27 -0
  97. data/lib/mongoid/extensions/set.rb +55 -0
  98. data/lib/mongoid/extensions/string.rb +155 -0
  99. data/lib/mongoid/extensions/symbol.rb +54 -0
  100. data/lib/mongoid/extensions/time.rb +78 -0
  101. data/lib/mongoid/extensions/time_with_zone.rb +55 -0
  102. data/lib/mongoid/extensions/true_class.rb +26 -0
  103. data/lib/mongoid/factory.rb +1 -1
  104. data/lib/mongoid/fields.rb +129 -194
  105. data/lib/mongoid/fields/foreign_key.rb +134 -0
  106. data/lib/mongoid/fields/localized.rb +73 -0
  107. data/lib/mongoid/fields/standard.rb +268 -0
  108. data/lib/mongoid/fields/validators.rb +2 -0
  109. data/lib/mongoid/fields/validators/macro.rb +83 -0
  110. data/lib/mongoid/finders.rb +42 -43
  111. data/lib/mongoid/hierarchy.rb +25 -14
  112. data/lib/mongoid/identity_map.rb +31 -19
  113. data/lib/mongoid/indexes.rb +66 -15
  114. data/lib/mongoid/indexes/validators/options.rb +80 -0
  115. data/lib/mongoid/inspection.rb +1 -1
  116. data/lib/mongoid/javascript.rb +1 -1
  117. data/lib/mongoid/json.rb +2 -2
  118. data/lib/mongoid/loggable.rb +69 -0
  119. data/lib/mongoid/matchers.rb +1 -1
  120. data/lib/mongoid/matchers/all.rb +7 -8
  121. data/lib/mongoid/matchers/and.rb +3 -3
  122. data/lib/mongoid/matchers/default.rb +6 -4
  123. data/lib/mongoid/matchers/exists.rb +2 -2
  124. data/lib/mongoid/matchers/gt.rb +2 -2
  125. data/lib/mongoid/matchers/gte.rb +2 -2
  126. data/lib/mongoid/matchers/in.rb +3 -7
  127. data/lib/mongoid/matchers/lt.rb +2 -2
  128. data/lib/mongoid/matchers/lte.rb +2 -2
  129. data/lib/mongoid/matchers/ne.rb +2 -2
  130. data/lib/mongoid/matchers/nin.rb +2 -2
  131. data/lib/mongoid/matchers/or.rb +2 -2
  132. data/lib/mongoid/matchers/size.rb +2 -2
  133. data/lib/mongoid/matchers/strategies.rb +3 -3
  134. data/lib/mongoid/multi_parameter_attributes.rb +8 -10
  135. data/lib/mongoid/nested_attributes.rb +17 -9
  136. data/lib/mongoid/observer.rb +1 -2
  137. data/lib/mongoid/paranoia.rb +13 -18
  138. data/lib/mongoid/persistence.rb +43 -39
  139. data/lib/mongoid/persistence/atomic.rb +2 -2
  140. data/lib/mongoid/persistence/atomic/add_to_set.rb +5 -9
  141. data/lib/mongoid/persistence/atomic/bit.rb +5 -7
  142. data/lib/mongoid/persistence/atomic/inc.rb +5 -7
  143. data/lib/mongoid/persistence/atomic/operation.rb +45 -6
  144. data/lib/mongoid/persistence/atomic/pop.rb +5 -7
  145. data/lib/mongoid/persistence/atomic/pull.rb +5 -7
  146. data/lib/mongoid/persistence/atomic/pull_all.rb +5 -7
  147. data/lib/mongoid/persistence/atomic/push.rb +4 -10
  148. data/lib/mongoid/persistence/atomic/push_all.rb +4 -10
  149. data/lib/mongoid/persistence/atomic/rename.rb +6 -7
  150. data/lib/mongoid/persistence/atomic/sets.rb +5 -7
  151. data/lib/mongoid/persistence/atomic/unset.rb +4 -5
  152. data/lib/mongoid/persistence/deletion.rb +2 -2
  153. data/lib/mongoid/persistence/insertion.rb +10 -16
  154. data/lib/mongoid/persistence/modification.rb +5 -9
  155. data/lib/mongoid/persistence/operations.rb +6 -19
  156. data/lib/mongoid/persistence/operations/embedded/insert.rb +7 -6
  157. data/lib/mongoid/persistence/operations/embedded/remove.rb +5 -5
  158. data/lib/mongoid/persistence/operations/insert.rb +4 -4
  159. data/lib/mongoid/persistence/operations/remove.rb +4 -4
  160. data/lib/mongoid/persistence/operations/update.rb +5 -5
  161. data/lib/mongoid/railtie.rb +26 -11
  162. data/lib/mongoid/railties/database.rake +22 -108
  163. data/lib/mongoid/relations.rb +4 -6
  164. data/lib/mongoid/relations/accessors.rb +119 -19
  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 +3 -3
  175. data/lib/mongoid/relations/builders.rb +19 -16
  176. data/lib/mongoid/relations/builders/embedded/in.rb +5 -5
  177. data/lib/mongoid/relations/builders/embedded/many.rb +12 -12
  178. data/lib/mongoid/relations/builders/embedded/one.rb +6 -6
  179. data/lib/mongoid/relations/builders/nested_attributes/many.rb +8 -8
  180. data/lib/mongoid/relations/builders/nested_attributes/one.rb +4 -4
  181. data/lib/mongoid/relations/builders/referenced/in.rb +4 -4
  182. data/lib/mongoid/relations/builders/referenced/many.rb +5 -5
  183. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +7 -5
  184. data/lib/mongoid/relations/builders/referenced/one.rb +5 -5
  185. data/lib/mongoid/relations/cascading.rb +6 -4
  186. data/lib/mongoid/relations/cascading/delete.rb +3 -5
  187. data/lib/mongoid/relations/cascading/destroy.rb +3 -3
  188. data/lib/mongoid/relations/cascading/nullify.rb +3 -3
  189. data/lib/mongoid/relations/cascading/restrict.rb +37 -0
  190. data/lib/mongoid/relations/constraint.rb +4 -3
  191. data/lib/mongoid/relations/conversions.rb +5 -6
  192. data/lib/mongoid/relations/cyclic.rb +7 -7
  193. data/lib/mongoid/relations/embedded/batchable.rb +346 -0
  194. data/lib/mongoid/relations/embedded/in.rb +23 -12
  195. data/lib/mongoid/relations/embedded/many.rb +99 -161
  196. data/lib/mongoid/relations/embedded/one.rb +25 -14
  197. data/lib/mongoid/relations/macros.rb +105 -61
  198. data/lib/mongoid/relations/many.rb +93 -14
  199. data/lib/mongoid/relations/metadata.rb +200 -45
  200. data/lib/mongoid/relations/nested_builder.rb +3 -5
  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 +60 -31
  205. data/lib/mongoid/relations/referenced/in.rb +40 -15
  206. data/lib/mongoid/relations/referenced/many.rb +117 -132
  207. data/lib/mongoid/relations/referenced/many_to_many.rb +101 -46
  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/reloading.rb +12 -14
  213. data/lib/mongoid/scoping.rb +329 -0
  214. data/lib/mongoid/serialization.rb +8 -27
  215. data/lib/mongoid/sessions.rb +359 -0
  216. data/lib/mongoid/sessions/factory.rb +106 -0
  217. data/lib/mongoid/sessions/mongo_uri.rb +93 -0
  218. data/lib/mongoid/sessions/validators.rb +2 -0
  219. data/lib/mongoid/sessions/validators/storage.rb +49 -0
  220. data/lib/mongoid/sharding.rb +6 -6
  221. data/lib/mongoid/state.rb +6 -7
  222. data/lib/mongoid/threaded.rb +167 -59
  223. data/lib/mongoid/threaded/lifecycle.rb +21 -22
  224. data/lib/mongoid/threaded/sessions.rb +0 -0
  225. data/lib/mongoid/timestamps.rb +1 -1
  226. data/lib/mongoid/timestamps/created.rb +8 -4
  227. data/lib/mongoid/timestamps/timeless.rb +6 -4
  228. data/lib/mongoid/timestamps/updated.rb +3 -3
  229. data/lib/mongoid/unit_of_work.rb +61 -0
  230. data/lib/mongoid/validations.rb +27 -19
  231. data/lib/mongoid/validations/associated.rb +2 -2
  232. data/lib/mongoid/validations/format.rb +2 -2
  233. data/lib/mongoid/validations/presence.rb +31 -5
  234. data/lib/mongoid/validations/uniqueness.rb +9 -12
  235. data/lib/mongoid/version.rb +2 -2
  236. data/lib/mongoid/versioning.rb +25 -26
  237. data/lib/rack/mongoid/middleware/identity_map.rb +3 -3
  238. data/lib/rails/generators/mongoid/config/config_generator.rb +1 -1
  239. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +59 -19
  240. data/lib/rails/generators/mongoid/model/model_generator.rb +7 -7
  241. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +2 -2
  242. data/lib/rails/generators/mongoid/observer/observer_generator.rb +4 -4
  243. data/lib/rails/generators/mongoid_generator.rb +5 -5
  244. data/lib/rails/mongoid.rb +69 -25
  245. metadata +110 -137
  246. checksums.yaml +0 -7
  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.rb +0 -120
  269. data/lib/mongoid/collections/master.rb +0 -45
  270. data/lib/mongoid/collections/operations.rb +0 -44
  271. data/lib/mongoid/config/database.rb +0 -181
  272. data/lib/mongoid/config/replset_database.rb +0 -80
  273. data/lib/mongoid/contexts.rb +0 -25
  274. data/lib/mongoid/contexts/enumerable.rb +0 -313
  275. data/lib/mongoid/contexts/enumerable/sort.rb +0 -43
  276. data/lib/mongoid/contexts/mongo.rb +0 -487
  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 -110
  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 -77
  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 -36
  341. data/lib/mongoid/named_scope.rb +0 -166
  342. data/lib/mongoid/relations/embedded/atomic.rb +0 -89
  343. data/lib/mongoid/relations/embedded/atomic/operation.rb +0 -63
  344. data/lib/mongoid/relations/embedded/atomic/pull.rb +0 -65
  345. data/lib/mongoid/relations/embedded/atomic/push_all.rb +0 -59
  346. data/lib/mongoid/relations/embedded/atomic/set.rb +0 -61
  347. data/lib/mongoid/relations/embedded/atomic/unset.rb +0 -41
  348. data/lib/mongoid/relations/referenced/batch.rb +0 -73
  349. data/lib/mongoid/relations/referenced/batch/insert.rb +0 -57
  350. data/lib/mongoid/safety.rb +0 -105
  351. data/lib/mongoid/scope.rb +0 -31
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
- module Mongoid #:nodoc:
3
- module Criterion #:nodoc:
4
- module Inspection #:nodoc:
2
+ module Mongoid
3
+ module Criterion
4
+ module Inspection
5
5
 
6
6
  # Get a pretty string representation of the criteria, including the
7
7
  # selector, options, matching count and documents for inspection.
@@ -10,12 +10,18 @@ module Mongoid #:nodoc:
10
10
  # criteria.inspect
11
11
  #
12
12
  # @return [ String ] The inspection string.
13
+ #
14
+ # @since 1.0.0
13
15
  def inspect
14
- "#<Mongoid::Criteria\n" <<
15
- " selector: #{selector.inspect},\n" <<
16
- " options: #{options.inspect},\n" <<
17
- " class: #{klass},\n" <<
18
- " embedded: #{embedded}>\n"
16
+ ::I18n.translate(
17
+ "mongoid.inspection.criteria",
18
+ {
19
+ selector: selector.inspect,
20
+ options: options.inspect,
21
+ klass: klass,
22
+ embedded: embedded?
23
+ }
24
+ )
19
25
  end
20
26
  end
21
27
  end
@@ -1,82 +1,152 @@
1
1
  # encoding: utf-8
2
- module Mongoid #:nodoc:
3
- module Criterion #:nodoc:
2
+ module Mongoid
3
+ module Criterion
4
4
  module Scoping
5
5
 
6
- attr_accessor :default_scopable
7
-
8
- # Apply the model's default scope to this criteria.
6
+ # Applies the default scope to the criteria.
9
7
  #
10
8
  # @example Apply the default scope.
11
9
  # criteria.apply_default_scope
12
10
  #
13
11
  # @return [ Criteria ] The criteria.
14
12
  #
15
- # @since 2.4.0
13
+ # @since 3.0.0
16
14
  def apply_default_scope
17
- if klass.default_scoping && default_scopable?
18
- self.default_scopable = false
19
- fuse(klass.default_scoping)
20
- else
21
- self
15
+ klass.without_default_scope do
16
+ merge!(klass.default_scoping.call)
17
+ end
18
+ self.scoping_options = true, false
19
+ end
20
+
21
+ # Given another criteria, remove the other criteria's scoping from this
22
+ # criteria.
23
+ #
24
+ # @example Remove the scoping.
25
+ # criteria.remove_scoping(other)
26
+ #
27
+ # @param [ Criteria ] other The other criteria.
28
+ #
29
+ # @return [ Criteria ] The criteria with scoping removed.
30
+ #
31
+ # @since 3.0.0
32
+ def remove_scoping(other)
33
+ if other
34
+ selector.reject! do |key, value|
35
+ other.selector[key] == value
36
+ end
37
+ options.reject! do |key, value|
38
+ other.options[key] == value
39
+ end
40
+ other.inclusions.each do |meta|
41
+ inclusions.delete_one(meta)
42
+ end
22
43
  end
44
+ self
23
45
  end
24
46
 
25
- # Is the default scope of the class allowed to be applied?
47
+ # Forces the criteria to be scoped, unless it's inside an unscoped block.
26
48
  #
27
- # @example Can the default scope be applied?
28
- # criteria.default_scopable?
49
+ # @example Force the criteria to be scoped.
50
+ # criteria.scoped(skip: 10)
29
51
  #
30
- # @return [ true, false ] The the default can be applied.
52
+ # @param [ Hash ] options Additional query options.
31
53
  #
32
- # @since 2.4.0
33
- def default_scopable?
34
- default_scopable != false
54
+ # @return [ Criteria ] The scoped criteria.
55
+ #
56
+ # @since 3.0.0
57
+ def scoped(options = nil)
58
+ crit = clone
59
+ crit.options.merge!(options || {})
60
+ if klass.default_scopable? && !scoped?
61
+ crit.apply_default_scope
62
+ end
63
+ crit
35
64
  end
36
65
 
37
- # Force the default scope to be applied to the criteria.
66
+ # Has the criteria had the default scope applied?
38
67
  #
39
- # @example Force default scoping.
40
- # criteria.scoped
68
+ # @example Is the default scope applied?
69
+ # criteria.scoped?
41
70
  #
42
- # @return [ Criteria ] The criteria.
71
+ # @return [ true, false ] If the default scope is applied.
43
72
  #
44
- # @since 2.4.0
45
- def scoped
46
- self.default_scopable = true
47
- apply_default_scope
73
+ # @since 3.0.0
74
+ def scoped?
75
+ !!(defined?(@scoped) ? @scoped : nil)
48
76
  end
49
77
 
50
- # Get the criteria with the default scoping removed.
78
+ # Clears all scoping from the criteria.
51
79
  #
52
- # @note This has slightly different behaviour than AR - will remove the
53
- # default scoping if no other criteria have been chained and tampered
54
- # with the criterion instead of clearing everything.
55
- #
56
- # @example Get the criteria unscoped.
80
+ # @example Clear all scoping from the criteria.
57
81
  # criteria.unscoped
58
82
  #
59
83
  # @return [ Criteria ] The unscoped criteria.
60
84
  #
61
- # @since 2.4.0
85
+ # @since 3.0.0
62
86
  def unscoped
63
- clone.tap do |criteria|
64
- criteria.clear_scoping
65
- criteria.default_scopable = false
87
+ crit = clone
88
+ unless unscoped?
89
+ crit.scoping_options = false, true
90
+ crit.selector.clear; crit.options.clear
66
91
  end
92
+ crit
93
+ end
94
+
95
+ # Is the criteria unscoped?
96
+ #
97
+ # @example Is the criteria unscoped?
98
+ # criteria.unscoped?
99
+ #
100
+ # @return [ true, false ] If the criteria is force unscoped.
101
+ #
102
+ # @since 3.0.0
103
+ def unscoped?
104
+ !!(defined?(@unscoped) ? @unscoped : nil)
67
105
  end
68
106
 
69
- # Remove all scoping from the criteria.
107
+ # Get the criteria scoping options, as a pair (scoped, unscoped).
70
108
  #
71
- # @example Remove the default scope.
72
- # criteria.clear_scoping
109
+ # @example Get the scoping options.
110
+ # criteria.scoping_options
73
111
  #
74
- # @return [ nil ] No guaranteed return value.
112
+ # @return [ Array ] Scoped, unscoped.
75
113
  #
76
- # @since 2.4.0
77
- def clear_scoping
78
- selector.clear
79
- options.clear
114
+ # @since 3.0.0
115
+ def scoping_options
116
+ [ (defined?(@scoped) ? @scoped : nil), (defined?(@unscoped) ? @unscoped : nil) ]
117
+ end
118
+
119
+ # Set the criteria scoping options, as a pair (scoped, unscoped).
120
+ #
121
+ # @example Set the scoping options.
122
+ # criteria.scoping_options = true, false
123
+ #
124
+ # @param [ Array ] options Scoped, unscoped.
125
+ #
126
+ # @return [ Array ] The new scoping options.
127
+ #
128
+ # @since 3.0.0
129
+ def scoping_options=(options)
130
+ @scoped, @unscoped = options
131
+ end
132
+
133
+ # Get the criteria with the default scope applied, if the default scope
134
+ # is able to be applied. Cases in which it cannot are: If we are in an
135
+ # unscoped block, if the criteria is already forced unscoped, or the
136
+ # default scope has already been applied.
137
+ #
138
+ # @example Get the criteria with the default scope.
139
+ # criteria.with_default_scope
140
+ #
141
+ # @return [ Criteria ] The criteria.
142
+ #
143
+ # @since 3.0.0
144
+ def with_default_scope
145
+ crit = clone
146
+ if klass.default_scopable? && !unscoped? && !scoped?
147
+ crit.apply_default_scope
148
+ end
149
+ crit
80
150
  end
81
151
  end
82
152
  end
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
- module Mongoid #:nodoc:
3
- module Dirty #:nodoc:
2
+ module Mongoid
3
+ module Dirty
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  # Get the changed attributes for the document.
@@ -24,7 +24,7 @@ module Mongoid #:nodoc:
24
24
  #
25
25
  # @since 2.4.0
26
26
  def changed?
27
- changed_attributes.any? || children_changed?
27
+ changes.values.any? { |val| val } || children_changed?
28
28
  end
29
29
 
30
30
  # Have any children (embedded documents) of this document changed?
@@ -62,11 +62,11 @@ module Mongoid #:nodoc:
62
62
  #
63
63
  # @since 2.4.0
64
64
  def changes
65
- changed.inject({}.with_indifferent_access) do |changes, attr|
66
- changes.tap do |hash|
67
- hash[attr] = attribute_change(attr)
68
- end
65
+ _changes = {}
66
+ changed.each do |attr|
67
+ _changes[attr] = attribute_change(attr)
69
68
  end
69
+ _changes
70
70
  end
71
71
 
72
72
  # Call this method after save, so the changes can be properly switched.
@@ -87,6 +87,18 @@ module Mongoid #:nodoc:
87
87
  changed_attributes.clear
88
88
  end
89
89
 
90
+ # Things that need to execute after a document has been persisted.
91
+ #
92
+ # @example Handle post persistence.
93
+ # document.post_persist
94
+ #
95
+ # @since 3.0.0
96
+ def post_persist
97
+ reset_persisted_children
98
+ move_changes
99
+ Threaded.clear_options!
100
+ end
101
+
90
102
  # Get the previous changes on the document.
91
103
  #
92
104
  # @example Get the previous changes.
@@ -96,7 +108,7 @@ module Mongoid #:nodoc:
96
108
  #
97
109
  # @since 2.4.0
98
110
  def previous_changes
99
- @previous_changes
111
+ @previous_changes ||= {}
100
112
  end
101
113
 
102
114
  # Remove a change from the dirty attributes hash. Used by the single field
@@ -115,36 +127,29 @@ module Mongoid #:nodoc:
115
127
  # Gets all the new values for each of the changed fields, to be passed to
116
128
  # a MongoDB $set modifier.
117
129
  #
118
- # @todo: Durran: Refactor 3.0
119
- #
120
130
  # @example Get the setters for the atomic updates.
121
131
  # person = Person.new(:title => "Sir")
122
132
  # person.title = "Madam"
123
133
  # person.setters # returns { "title" => "Madam" }
124
134
  #
125
135
  # @return [ Hash ] A +Hash+ of atomic setters.
136
+ #
137
+ # @since 2.0.0
126
138
  def setters
127
- {}.tap do |modifications|
128
- changes.each_pair do |name, changes|
129
- if changes
130
- old, new = changes
131
- field = fields[name]
132
- key = embedded? ? "#{atomic_position}.#{name}" : name
133
- if field && field.resizable?
134
- field.add_atomic_changes(
135
- self,
136
- name,
137
- key,
138
- modifications,
139
- new,
140
- old
141
- )
142
- else
143
- modifications[key] = new
144
- end
139
+ mods = {}
140
+ changes.each_pair do |name, changes|
141
+ if changes
142
+ old, new = changes
143
+ field = fields[name]
144
+ key = atomic_attribute_name(name)
145
+ if field && field.resizable?
146
+ field.add_atomic_changes(self, name, key, mods, new, old)
147
+ else
148
+ mods[key] = new unless atomic_unsets.include?(key)
145
149
  end
146
150
  end
147
151
  end
152
+ mods
148
153
  end
149
154
 
150
155
  private
@@ -178,6 +183,22 @@ module Mongoid #:nodoc:
178
183
  changed_attributes[attr] != attributes[attr]
179
184
  end
180
185
 
186
+ # Get whether or not the field has a different value from the default.
187
+ #
188
+ # @example Is the field different from the default?
189
+ # model.attribute_changed_from_default?
190
+ #
191
+ # @param [ String ] attr The name of the attribute.
192
+ #
193
+ # @return [ true, false ] If the attribute differs.
194
+ #
195
+ # @since 3.0.0
196
+ def attribute_changed_from_default?(attr)
197
+ field = fields[attr]
198
+ return false unless field
199
+ attributes[attr] != field.eval_default(self)
200
+ end
201
+
181
202
  # Get the previous value for the attribute.
182
203
  #
183
204
  # @example Get the previous value.
@@ -202,7 +223,7 @@ module Mongoid #:nodoc:
202
223
  # @since 2.3.0
203
224
  def attribute_will_change!(attr)
204
225
  unless changed_attributes.has_key?(attr)
205
- changed_attributes[attr] = read_attribute(attr)._deep_copy
226
+ changed_attributes[attr] = read_attribute(attr).__deep_copy__
206
227
  end
207
228
  end
208
229
 
@@ -220,7 +241,7 @@ module Mongoid #:nodoc:
220
241
  attributes[attr] = changed_attributes[attr] if attribute_changed?(attr)
221
242
  end
222
243
 
223
- module ClassMethods #:nodoc:
244
+ module ClassMethods
224
245
 
225
246
  private
226
247
 
@@ -236,49 +257,113 @@ module Mongoid #:nodoc:
236
257
  #
237
258
  # @since 2.4.0
238
259
  def create_dirty_methods(name, meth)
239
- generated_methods.module_eval do
240
- if meth =~ /\W/
241
- define_method("#{meth}_change") do
242
- attribute_change(name)
243
- end
244
-
245
- define_method("#{meth}_changed?") do
246
- attribute_changed?(name)
247
- end
248
-
249
- define_method("#{meth}_was") do
250
- attribute_was(name)
251
- end
260
+ create_dirty_change_accessor(name, meth)
261
+ create_dirty_change_check(name, meth)
262
+ create_dirty_change_flag(name, meth)
263
+ create_dirty_default_change_check(name, meth)
264
+ create_dirty_previous_value_accessor(name, meth)
265
+ create_dirty_reset(name, meth)
266
+ create_dirty_reset(name, meth)
267
+ end
252
268
 
253
- define_method("#{meth}_will_change!") do
254
- attribute_will_change!(name)
255
- end
269
+ # Creates the dirty change accessor.
270
+ #
271
+ # @example Create the accessor.
272
+ # Model.create_dirty_change_accessor("name", "alias")
273
+ #
274
+ # @param [ String ] name The attribute name.
275
+ # @param [ String ] meth The name of the accessor.
276
+ #
277
+ # @since 3.0.0
278
+ def create_dirty_change_accessor(name, meth)
279
+ generated_methods.module_eval do
280
+ re_define_method("#{meth}_change") do
281
+ attribute_change(name)
282
+ end
283
+ end
284
+ end
256
285
 
257
- define_method("reset_#{meth}!") do
258
- reset_attribute!(name)
259
- end
260
- else
261
- class_eval <<-EOM
262
- def #{meth}_change
263
- attribute_change(#{name.inspect})
264
- end
286
+ # Creates the dirty change check.
287
+ #
288
+ # @example Create the check.
289
+ # Model.create_dirty_change_check("name", "alias")
290
+ #
291
+ # @param [ String ] name The attribute name.
292
+ # @param [ String ] meth The name of the accessor.
293
+ #
294
+ # @since 3.0.0
295
+ def create_dirty_change_check(name, meth)
296
+ generated_methods.module_eval do
297
+ re_define_method("#{meth}_changed?") do
298
+ attribute_changed?(name)
299
+ end
300
+ end
301
+ end
265
302
 
266
- def #{meth}_changed?
267
- attribute_changed?(#{name.inspect})
268
- end
303
+ # Creates the dirty default change check.
304
+ #
305
+ # @example Create the check.
306
+ # Model.create_dirty_default_change_check("name", "alias")
307
+ #
308
+ # @param [ String ] name The attribute name.
309
+ # @param [ String ] meth The name of the accessor.
310
+ #
311
+ # @since 3.0.0
312
+ def create_dirty_default_change_check(name, meth)
313
+ generated_methods.module_eval do
314
+ re_define_method("#{meth}_changed_from_default?") do
315
+ attribute_changed_from_default?(name)
316
+ end
317
+ end
318
+ end
269
319
 
270
- def #{meth}_was
271
- attribute_was(#{name.inspect})
272
- end
320
+ # Creates the dirty change previous value accessor.
321
+ #
322
+ # @example Create the accessor.
323
+ # Model.create_dirty_previous_value_accessor("name", "alias")
324
+ #
325
+ # @param [ String ] name The attribute name.
326
+ # @param [ String ] meth The name of the accessor.
327
+ #
328
+ # @since 3.0.0
329
+ def create_dirty_previous_value_accessor(name, meth)
330
+ generated_methods.module_eval do
331
+ re_define_method("#{meth}_was") do
332
+ attribute_was(name)
333
+ end
334
+ end
335
+ end
273
336
 
274
- def #{meth}_will_change!
275
- attribute_will_change!(#{name.inspect})
276
- end
337
+ # Creates the dirty change flag.
338
+ #
339
+ # @example Create the flag.
340
+ # Model.create_dirty_change_flag("name", "alias")
341
+ #
342
+ # @param [ String ] name The attribute name.
343
+ # @param [ String ] meth The name of the accessor.
344
+ #
345
+ # @since 3.0.0
346
+ def create_dirty_change_flag(name, meth)
347
+ generated_methods.module_eval do
348
+ re_define_method("#{meth}_will_change!") do
349
+ attribute_will_change!(name)
350
+ end
351
+ end
352
+ end
277
353
 
278
- def reset_#{meth}!
279
- reset_attribute!(#{name.inspect})
280
- end
281
- EOM
354
+ # Creates the dirty change reset.
355
+ #
356
+ # @example Create the reset.
357
+ # Model.create_dirty_reset("name", "alias")
358
+ #
359
+ # @param [ String ] name The attribute name.
360
+ # @param [ String ] meth The name of the accessor.
361
+ #
362
+ # @since 3.0.0
363
+ def create_dirty_reset(name, meth)
364
+ generated_methods.module_eval do
365
+ re_define_method("reset_#{meth}!") do
366
+ reset_attribute!(name)
282
367
  end
283
368
  end
284
369
  end