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,34 +0,0 @@
1
- # encoding: utf-8
2
- module Mongoid #:nodoc:
3
- module Criterion #:nodoc:
4
-
5
- # This module defines criteria behavior for building documents for
6
- # specified conditions.
7
- module Builder
8
-
9
- # Build a document given the selector and return it.
10
- # Complex criteria, such as $in and $or operations will get ignored.
11
- #
12
- # @example build the document.
13
- # Person.where(:title => "Sir").build
14
- #
15
- # @example Build with selectors getting ignored.
16
- # Person.where(:age.gt => 5).build
17
- #
18
- # @return [ Document ] A non-persisted document.
19
- #
20
- # @since 2.0.0
21
- def build(attrs = {})
22
- klass.new(
23
- selector.inject(attrs) do |hash, (key, value)|
24
- hash.tap do |attrs|
25
- unless key.to_s =~ /\$/ || value.is_a?(Hash)
26
- attrs[key] = value
27
- end
28
- end
29
- end
30
- )
31
- end
32
- end
33
- end
34
- end
@@ -1,84 +0,0 @@
1
- # encoding: utf-8
2
- module Mongoid #:nodoc:
3
- module Criterion #:nodoc:
4
-
5
- # Complex criterion are used when performing operations on symbols to get
6
- # get a shorthand syntax for where clauses.
7
- #
8
- # @example Conversion of a simple to complex criterion.
9
- # { :field => { "$lt" => "value" } }
10
- # becomes:
11
- # { :field.lt => "value }
12
- class Complex
13
- attr_accessor :key, :operator
14
-
15
- # Create the new complex criterion.
16
- #
17
- # @example Instantiate a new complex criterion.
18
- # Complex.new(:key => :field, :operator => "$gt")
19
- #
20
- # @param [ Hash ] opts The options to convert.
21
- def initialize(opts = {})
22
- @key, @operator = opts[:key], opts[:operator]
23
- end
24
-
25
- # Get the criterion as a hash.
26
- #
27
- # @example Get the criterion as a hash.
28
- # criterion.hash
29
- #
30
- # @return [ Hash ] The keys and operators.
31
- def hash
32
- [@key, @operator].hash
33
- end
34
-
35
- # Create a mongo query with given value
36
- #
37
- # @example Create query
38
- # criterion.to_mongo_hash(value)
39
- #
40
- # @params [] Whatever is a valid input for given operator
41
- # @return [ Hash ] The query
42
- def to_mongo_query(v)
43
- {"$#{self.operator}" => v}
44
- end
45
-
46
- # Is the criterion equal to the other?
47
- #
48
- # @example Check equality.
49
- # criterion.eql?(other)
50
- #
51
- # @param [ Complex ] other The other complex criterion.
52
- #
53
- # @return [ true, false ] If they are equal.
54
- def eql?(other)
55
- self == (other)
56
- end
57
-
58
- # Is the criterion equal to the other?
59
- #
60
- # @example Check equality.
61
- # criterion == other
62
- #
63
- # @param [ Complex ] other The other complex criterion.
64
- #
65
- # @return [ true, false ] If they are equal.
66
- def ==(other)
67
- return false unless other.is_a?(self.class)
68
- self.key == other.key && self.operator == other.operator
69
- end
70
-
71
- # Returns the name of the key as a string.
72
- #
73
- # @example Get the name of the key.
74
- # criterion.to_s
75
- #
76
- # @return [ String ] The field name.
77
- #
78
- # @since 2.1.0
79
- def to_s
80
- key.to_s
81
- end
82
- end
83
- end
84
- end
@@ -1,34 +0,0 @@
1
- # encoding: utf-8
2
- module Mongoid #:nodoc:
3
- module Criterion #:nodoc:
4
-
5
- # This module defines criteria behavior for creating documents in the
6
- # database for specified conditions.
7
- module Creational
8
-
9
- # Create a document in the database given the selector and return it.
10
- # Complex criteria, such as $in and $or operations will get ignored.
11
- #
12
- # @example Create the document.
13
- # Person.where(:title => "Sir").create
14
- #
15
- # @example Create with selectors getting ignored.
16
- # Person.where(:age.gt => 5).create
17
- #
18
- # @return [ Document ] A newly created document.
19
- #
20
- # @since 2.0.0.rc.1
21
- def create(attrs = {})
22
- klass.create(
23
- selector.inject(attrs) do |hash, (key, value)|
24
- hash.tap do |attrs|
25
- unless key.to_s =~ /\$/ || value.is_a?(Hash)
26
- attrs[key] = value
27
- end
28
- end
29
- end
30
- )
31
- end
32
- end
33
- end
34
- end
@@ -1,110 +0,0 @@
1
- # encoding: utf-8
2
- module Mongoid #:nodoc:
3
- module Criterion #:nodoc:
4
-
5
- # This module contains criteria behaviour for exclusion of values.
6
- module Exclusion
7
-
8
- # Adds a criterion to the +Criteria+ that specifies values that are not
9
- # allowed to match any document in the database. The MongoDB
10
- # conditional operator that will be used is "$ne".
11
- #
12
- # @example Match documents without these values.
13
- # criteria.excludes(:field => "value1")
14
- # criteria.excludes(:field1 => "value1", :field2 => "value1")
15
- #
16
- # @param [ Hash ] attributes: A +Hash+ where the key is the field
17
- # name and the value is a value that must not be equal to the
18
- # corresponding field value in the database.
19
- #
20
- # @return [ Criteria ] A newly cloned copy.
21
- def excludes(attributes = {})
22
- mongo_id = attributes.delete(:id)
23
- attributes = attributes.merge(:_id => mongo_id) if mongo_id
24
- update_selector(attributes, "$ne")
25
- end
26
-
27
- # Used when wanting to set the fields options directly using a hash
28
- # instead of going through only or without.
29
- #
30
- # @example Set the limited fields.
31
- # criteria.fields(:field => 1)
32
- #
33
- # @param [ Hash ] attributes The field options.
34
- #
35
- # @return [ Criteria ] A newly cloned copy.
36
- #
37
- # @since 2.0.2
38
- def fields(attributes = nil)
39
- clone.tap { |crit| crit.options[:fields] = attributes || {} }
40
- end
41
-
42
- # Adds a criterion to the +Criteria+ that specifies values where none
43
- # should match in order to return results. This is similar to an SQL
44
- # "NOT IN" clause. The MongoDB conditional operator that will be
45
- # used is "$nin".
46
- #
47
- # @example Match documents with values not in the provided.
48
- # criteria.not_in(:field => ["value1", "value2"])
49
- # criteria.not_in(:field1 => ["value1", "value2"], :field2 => ["value1"])
50
- #
51
- # @param [ Hash ] attributes A +Hash+ where the key is the field name
52
- # and the value is an +Array+ of values that none can match.
53
- #
54
- # @return [ Criteria ] A newly cloned copy.
55
- def not_in(attributes)
56
- update_selector(attributes, "$nin")
57
- end
58
-
59
- # Adds a criterion to the +Criteria+ that specifies the fields that will
60
- # get returned from the Document. Used mainly for list views that do not
61
- # require all fields to be present. This is similar to SQL "SELECT" values.
62
- #
63
- # @example Limit the fields to only the specified.
64
- # criteria.only(:field1, :field2, :field3)
65
- #
66
- # @note #only and #without cannot be used together.
67
- #
68
- # @param [ Array<Symbol> ] args A list of field names to limit to.
69
- #
70
- # @return [ Criteria ] A newly cloned copy.
71
- def only(*args)
72
- clone.tap do |crit|
73
- if args.any?
74
- crit.options[:fields] = {:_type => 1}
75
- crit.field_list = args.flatten
76
- crit.field_list.each do |f|
77
- crit.options[:fields][f] = 1
78
- end
79
- end
80
- end
81
- end
82
-
83
- # Adds a criterion to the +Criteria+ that specifies the fields that will
84
- # not get returned by the document.
85
- #
86
- # @example Filter out specific fields.
87
- # criteria.without(:field2, :field2)
88
- #
89
- # @note #only and #without cannot be used together.
90
- #
91
- # @param [ Array<Symbol> args A list of fields to exclude.
92
- #
93
- # @return [ Criteria ] A newly cloned copy.
94
- #
95
- # @since 2.0.0
96
- def without(*args)
97
- clone.tap do |crit|
98
- if args.any?
99
- unless args == [ :id ] || args == [ :_id ]
100
- crit.options[:fields] = {}
101
- end
102
- args.flatten.each do |f|
103
- crit.options[:fields][f] = 0
104
- end
105
- end
106
- end
107
- end
108
- end
109
- end
110
- end
@@ -1,290 +0,0 @@
1
- # encoding: utf-8
2
- module Mongoid #:nodoc:
3
- module Criterion #:nodoc:
4
- module Inclusion
5
-
6
- # Adds a criterion to the +Criteria+ that specifies values that must all
7
- # be matched in order to return results. Similar to an "in" clause but the
8
- # underlying conditional logic is an "AND" and not an "OR". The MongoDB
9
- # conditional operator that will be used is "$all".
10
- #
11
- # @example Adding the criterion.
12
- # criteria.all(:field => ["value1", "value2"])
13
- # criteria.all(:field1 => ["value1", "value2"], :field2 => ["value1"])
14
- #
15
- # @param [ Hash ] attributes Name/value pairs that all must match.
16
- #
17
- # @return [ Criteria ] A new criteria with the added selector.
18
- def all(attributes = {})
19
- update_selector(attributes, "$all")
20
- end
21
- alias :all_in :all
22
-
23
- # Adds a criterion to the criteria that specifies multiple expressions
24
- # that *all* must match. This uses MongoDB's $and operator under the
25
- # covers.
26
- #
27
- # @example Match all provided expressions.
28
- # criteria.all_of(:name => value, :age.gt => 18)
29
- #
30
- # @param [ Array<Hash> ] Multiple hash expressions.
31
- #
32
- # @return [ Criteria ] The criteria object.
33
- #
34
- # @since 2.3.0
35
- def all_of(*args)
36
- clone.tap do |crit|
37
- unless args.empty?
38
- criterion = @selector["$and"] || []
39
- converted = BSON::ObjectId.convert(klass, args.flatten)
40
- expanded = converted.collect { |hash| hash.expand_complex_criteria }
41
- crit.selector["$and"] = criterion.concat(expanded)
42
- end
43
- end
44
- end
45
-
46
- # Adds a criterion to the +Criteria+ that specifies values where any can
47
- # be matched in order to return results. This is similar to an SQL "IN"
48
- # clause. The MongoDB conditional operator that will be used is "$in".
49
- # Any previously matching "$in" arrays will be unioned with new
50
- # arguments.
51
- #
52
- # @example Adding the criterion.
53
- # criteria.in(:field => ["value1"]).also_in(:field => ["value2"])
54
- #
55
- # @param [ Hash ] attributes Name/value pairs any can match.
56
- #
57
- # @return [ Criteria ] A new criteria with the added selector.
58
- def also_in(attributes = {})
59
- update_selector(attributes, "$in")
60
- end
61
-
62
- # Adds a criterion to the +Criteria+ that specifies values that must
63
- # be matched in order to return results. This is similar to a SQL "WHERE"
64
- # clause. This is the actual selector that will be provided to MongoDB,
65
- # similar to the Javascript object that is used when performing a find()
66
- # in the MongoDB console.
67
- #
68
- # @example Adding the criterion.
69
- # criteria.and(:field1 => "value1", :field2 => 15)
70
- #
71
- # @param [ Hash ] selectior Name/value pairs that all must match.
72
- #
73
- # @return [ Criteria ] A new criteria with the added selector.
74
- def and(selector = nil)
75
- where(selector)
76
- end
77
-
78
- # Adds a criterion to the +Criteria+ that specifies a set of expressions
79
- # to match if any of them return true. This is a $or query in MongoDB and
80
- # is similar to a SQL OR. This is named #any_of and aliased "or" for
81
- # readability.
82
- #
83
- # @example Adding the criterion.
84
- # criteria.any_of({ :field1 => "value" }, { :field2 => "value2" })
85
- #
86
- # @param [ Array<Hash> ] args A list of name/value pairs any can match.
87
- #
88
- # @return [ Criteria ] A new criteria with the added selector.
89
- def any_of(*args)
90
- clone.tap do |crit|
91
- criterion = @selector["$or"] || []
92
- converted = BSON::ObjectId.convert(klass, args.flatten)
93
- expanded = converted.collect { |hash| hash.expand_complex_criteria }
94
- crit.selector["$or"] = criterion.concat(expanded)
95
- end
96
- end
97
- alias :or :any_of
98
-
99
- # Find the matchind document in the criteria, either based on id or
100
- # conditions.
101
- #
102
- # @todo Durran: DRY up duplicated code in a few places.
103
- #
104
- # @example Find by an id.
105
- # criteria.find(BSON::ObjectId.new)
106
- #
107
- # @example Find by multiple ids.
108
- # criteria.find([ BSON::ObjectId.new, BSON::ObjectId.new ])
109
- #
110
- # @example Conditionally find all matching documents.
111
- # criteria.find(:all, :conditions => { :title => "Sir" })
112
- #
113
- # @example Conditionally find the first document.
114
- # criteria.find(:first, :conditions => { :title => "Sir" })
115
- #
116
- # @example Conditionally find the last document.
117
- # criteria.find(:last, :conditions => { :title => "Sir" })
118
- #
119
- # @param [ Symbol, BSON::ObjectId, Array<BSON::ObjectId> ] arg The
120
- # argument to search with.
121
- # @param [ Hash ] options The options to search with.
122
- #
123
- # @return [ Document, Criteria ] The matching document(s).
124
- def find(*args)
125
- type, crit = search(*args)
126
- case type
127
- when :first then crit.one
128
- when :last then crit.last
129
- when :ids then crit.execute_or_raise(args)
130
- else
131
- crit
132
- end
133
- end
134
-
135
- # Execute the criteria or raise an error if no documents found.
136
- #
137
- # @example Execute or raise
138
- # criteria.execute_or_raise(id, criteria)
139
- #
140
- # @param [ Object ] args The arguments passed.
141
- # @param [ Criteria ] criteria The criteria to execute.
142
- #
143
- # @raise [ Errors::DocumentNotFound ] If nothing returned.
144
- #
145
- # @return [ Document, Array<Document> ] The document(s).
146
- #
147
- # @since 2.0.0
148
- def execute_or_raise(args)
149
- (args[0].is_a?(Array) ? entries : from_map_or_db).tap do |result|
150
- if Mongoid.raise_not_found_error && !args.flatten.blank?
151
- raise Errors::DocumentNotFound.new(klass, args) if result._vacant?
152
- end
153
- end
154
- end
155
-
156
- # Get the document from the identity map, and if not found hit the
157
- # database.
158
- #
159
- # @example Get the document from the map or criteria.
160
- # criteria.from_map_or_db(criteria)
161
- #
162
- # @param [ Criteria ] The cloned criteria.
163
- #
164
- # @return [ Document ] The found document.
165
- #
166
- # @since 2.2.1
167
- def from_map_or_db
168
- doc = IdentityMap.get(klass, extract_id || selector)
169
- doc && doc.matches?(selector) ? doc : first
170
- end
171
-
172
- # Adds a criterion to the +Criteria+ that specifies values where any can
173
- # be matched in order to return results. This is similar to an SQL "IN"
174
- # clause. The MongoDB conditional operator that will be used is "$in".
175
- #
176
- # @example Adding the criterion.
177
- # criteria.in(:field => ["value1", "value2"])
178
- # criteria.in(:field1 => ["value1", "value2"], :field2 => ["value1"])
179
- #
180
- # @param [ Hash ] attributes Name/value pairs any can match.
181
- #
182
- # @return [ Criteria ] A new criteria with the added selector.
183
- def in(attributes = {})
184
- update_selector(attributes, "$in", :&)
185
- end
186
- alias :any_in :in
187
-
188
- # Eager loads all the provided relations. Will load all the documents
189
- # into the identity map who's ids match based on the extra query for the
190
- # ids.
191
- #
192
- # @note This will only work if Mongoid's identity map is enabled. To do
193
- # so set identity_map_enabled: true in your mongoid.yml
194
- #
195
- # @note This will work for embedded relations that reference another
196
- # collection via belongs_to as well.
197
- #
198
- # @note Eager loading brings all the documents into memory, so there is a
199
- # sweet spot on the performance gains. Internal benchmarks show that
200
- # eager loading becomes slower around 100k documents, but this will
201
- # naturally depend on the specific application.
202
- #
203
- # @example Eager load the provided relations.
204
- # Person.includes(:posts, :game)
205
- #
206
- # @param [ Array<Symbol> ] relations The names of the relations to eager
207
- # load.
208
- #
209
- # @return [ Criteria ] The cloned criteria.
210
- #
211
- # @since 2.2.0
212
- def includes(*relations)
213
- relations.flatten.each do |name|
214
- inclusions.push(klass.reflect_on_association(name))
215
- end
216
- clone
217
- end
218
-
219
- # Get a list of criteria that are to be executed for eager loading.
220
- #
221
- # @example Get the eager loading inclusions.
222
- # Person.includes(:game).inclusions
223
- #
224
- # @return [ Array<Metadata> ] The inclusions.
225
- #
226
- # @since 2.2.0
227
- def inclusions
228
- @inclusions ||= []
229
- end
230
-
231
- # Adds a criterion to the +Criteria+ that specifies values to do
232
- # geospacial searches by. The field must be indexed with the "2d" option.
233
- #
234
- # @example Adding the criterion.
235
- # criteria.near(:field1 => [30, -44])
236
- #
237
- # @param [ Hash ] attributes The fields with lat/long values.
238
- #
239
- # @return [ Criteria ] A new criteria with the added selector.
240
- def near(attributes = {})
241
- update_selector(attributes, "$near")
242
- end
243
-
244
- # Adds a criterion to the +Criteria+ that specifies values that must
245
- # be matched in order to return results. This is similar to a SQL "WHERE"
246
- # clause. This is the actual selector that will be provided to MongoDB,
247
- # similar to the Javascript object that is used when performing a find()
248
- # in the MongoDB console.
249
- #
250
- # @example Adding the criterion.
251
- # criteria.where(:field1 => "value1", :field2 => 15)
252
- #
253
- # @param [ Hash ] selector Name/value pairs where all must match.
254
- #
255
- # @return [ Criteria ] A new criteria with the added selector.
256
- def where(selector = nil)
257
- clone.tap do |crit|
258
- selector = case selector
259
- when String then {"$where" => selector}
260
- else
261
- BSON::ObjectId.convert(klass, selector || {}, false).expand_complex_criteria
262
- end
263
-
264
- # @todo: Durran: 3.0.0: refactor the merging into separate strategies
265
- # to clean this funkiness up.
266
- selector.each_pair do |key, value|
267
- if crit.selector.has_key?(key)
268
- if key.mongoid_id?
269
- if crit.selector.has_key?("$and")
270
- crit.selector["$and"] << { key => value }
271
- elsif crit.selector[key] != value
272
- crit.selector["$and"] = [{ key => crit.selector.delete(key) }, { key => value }]
273
- end
274
- elsif crit.selector[key].respond_to?(:merge) && value.respond_to?(:merge)
275
- crit.selector[key] =
276
- crit.selector[key].merge(value) do |key, old, new|
277
- key == '$in' ? old & new : new
278
- end
279
- else
280
- crit.selector[key] = value
281
- end
282
- else
283
- crit.selector[key] = value
284
- end
285
- end
286
- end
287
- end
288
- end
289
- end
290
- end