mongoid 2.4.10 → 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 +843 -9
  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 -9
  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 +1 -1
  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 +31 -19
  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 +3 -5
  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 -160
  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 +2 -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 -128
  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 +8 -10
  234. data/lib/mongoid/validations.rb +28 -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 +92 -154
  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 -487
  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 -36
  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
@@ -1,12 +1,12 @@
1
1
  # encoding: utf-8
2
- module Mongoid # :nodoc:
3
- module Relations #:nodoc:
2
+ module Mongoid
3
+ module Relations
4
4
 
5
5
  # The "Grand Poobah" of information about any relation is this class. It
6
6
  # contains everything you could ever possible want to know.
7
7
  class Metadata < Hash
8
8
 
9
- delegate :foreign_key_default, :stores_foreign_key?, :to => :relation
9
+ delegate :foreign_key_default, :stores_foreign_key?, to: :relation
10
10
 
11
11
  # Returns the as option of the relation.
12
12
  #
@@ -32,6 +32,19 @@ module Mongoid # :nodoc:
32
32
  !!as
33
33
  end
34
34
 
35
+ # Is the relation autobuilding if accessed via the getter and the
36
+ # document is new.
37
+ #
38
+ # @example Is the relation autobuilding?
39
+ # metadata.autobuilding?
40
+ #
41
+ # @return [ true, false ] If the relation autobuilds.
42
+ #
43
+ # @since 3.0.0
44
+ def autobuilding?
45
+ !!self[:autobuild]
46
+ end
47
+
35
48
  # Returns the autosave option of the relation.
36
49
  #
37
50
  # @example Get the autosave option.
@@ -82,11 +95,7 @@ module Mongoid # :nodoc:
82
95
  # @since 2.0.0.rc.1
83
96
  def cascade_strategy
84
97
  if dependent?
85
- strategy =
86
- %{Mongoid::Relations::Cascading::#{dependent.to_s.classify}}
87
- strategy.constantize
88
- else
89
- return nil
98
+ "Mongoid::Relations::Cascading::#{dependent.to_s.classify}".constantize
90
99
  end
91
100
  end
92
101
 
@@ -135,11 +144,12 @@ module Mongoid # :nodoc:
135
144
  # metadata.criteria([ id_one, id_two ])
136
145
  #
137
146
  # @param [ Object ] object The foreign key used for the query.
147
+ # @param [ Class ] type The base class.
138
148
  #
139
149
  # @return [ Criteria ] The criteria.
140
150
  #
141
151
  # @since 2.1.0
142
- def criteria(object, type = nil)
152
+ def criteria(object, type)
143
153
  query = relation.criteria(self, object, type)
144
154
  order ? query.order_by(order) : query
145
155
  end
@@ -348,19 +358,40 @@ module Mongoid # :nodoc:
348
358
  #
349
359
  # @since 2.0.0.rc.1
350
360
  def inspect
351
- "#<Mongoid::Relations::Metadata\n" <<
352
- " class_name: #{class_name},\n" <<
353
- " cyclic: #{cyclic || "No"},\n" <<
354
- " dependent: #{dependent || "None"},\n" <<
355
- " inverse_of: #{inverse_of || "N/A"},\n" <<
356
- " key: #{key},\n" <<
357
- " macro: #{macro},\n" <<
358
- " name: #{name},\n" <<
359
- " order: #{order.inspect || "No"},\n" <<
360
- " polymorphic: #{polymorphic? || "No"},\n" <<
361
- " relation: #{relation},\n" <<
362
- " setter: #{setter},\n" <<
363
- " versioned: #{versioned? || "No"}>\n"
361
+ ::I18n.translate(
362
+ "mongoid.inspection.metadata",
363
+ {
364
+ autobuild: autobuilding?,
365
+ class_name: class_name,
366
+ cyclic: cyclic.inspect,
367
+ dependent: dependent.inspect,
368
+ inverse_of: inverse_of.inspect,
369
+ key: key,
370
+ locale: :en,
371
+ macro: macro,
372
+ name: name,
373
+ order: order.inspect,
374
+ polymorphic: polymorphic?,
375
+ relation: relation,
376
+ setter: setter,
377
+ versioned: versioned?
378
+ }
379
+ )
380
+ end
381
+
382
+ # Get the name of the inverse relations if they exists. If this is a
383
+ # polymorphic relation then just return the :as option that was defined.
384
+ #
385
+ # @example Get the names of the inverses.
386
+ # metadata.inverses
387
+ #
388
+ # @param [ Document ] other The document to aid in the discovery.
389
+ #
390
+ # @return [ Array<Symbol> ] The inverse name.
391
+ def inverses(other = nil)
392
+ return [self[:inverse_of]] if has_key?(:inverse_of)
393
+ return self[:as] ? [self[:as]] : lookup_inverses(other) if polymorphic?
394
+ @inverse ||= [(cyclic? ? cyclic_inverse : inverse_relation)]
364
395
  end
365
396
 
366
397
  # Get the name of the inverse relation if it exists. If this is a
@@ -375,9 +406,8 @@ module Mongoid # :nodoc:
375
406
  #
376
407
  # @since 2.0.0.rc.1
377
408
  def inverse(other = nil)
378
- return self[:inverse_of] if has_key?(:inverse_of)
379
- return self[:as] || lookup_inverse(other) if polymorphic?
380
- @inverse ||= (cyclic? ? cyclic_inverse : inverse_relation)
409
+ invs = inverses(other)
410
+ invs.first if invs.count == 1
381
411
  end
382
412
 
383
413
  # Returns the inverse_class_name option of the relation.
@@ -479,7 +509,8 @@ module Mongoid # :nodoc:
479
509
  #
480
510
  # @since 2.0.0.rc.1
481
511
  def inverse_setter(other = nil)
482
- "#{inverse(other)}="
512
+ inv = inverse(other)
513
+ inv ? "#{inv}=" : nil
483
514
  end
484
515
 
485
516
  # Returns the name of the field in which to store the name of the class
@@ -492,8 +523,7 @@ module Mongoid # :nodoc:
492
523
  #
493
524
  # @since 2.0.0.rc.1
494
525
  def inverse_type
495
- @inverse_type ||=
496
- relation.stores_foreign_key? && polymorphic? ? "#{name}_type" : nil
526
+ @inverse_type ||= determine_inverse_for(:type)
497
527
  end
498
528
 
499
529
  # Gets the setter for the field that sets the type of document on a
@@ -509,6 +539,31 @@ module Mongoid # :nodoc:
509
539
  @inverse_type_setter ||= inverse_type ? "#{inverse_type}=" : nil
510
540
  end
511
541
 
542
+ # Returns the name of the field in which to store the name of the inverse
543
+ # field for the polymorphic relation.
544
+ #
545
+ # @example Get the name of the field.
546
+ # metadata.inverse_of_field
547
+ #
548
+ # @return [ String ] The name of the field for storing the name of the
549
+ # inverse field.
550
+ #
551
+ # @since 2.4.5
552
+ def inverse_of_field
553
+ @inverse_of_field ||= determine_inverse_for(:field)
554
+ end
555
+
556
+ # Gets the setter for the field that stores the name of the inverse field
557
+ # on a polymorphic relation.
558
+ #
559
+ # @example Get the inverse type setter.
560
+ # metadata.inverse_of_field_setter
561
+ #
562
+ # @return [ String ] The name of the setter.
563
+ def inverse_of_field_setter
564
+ @inverse_of_field_setter ||= inverse_of_field ? "#{inverse_of_field}=" : nil
565
+ end
566
+
512
567
  # This returns the key that is to be used to grab the attributes for the
513
568
  # relation or the foreign key or id that a referenced relation will use
514
569
  # to query for the object.
@@ -689,6 +744,17 @@ module Mongoid # :nodoc:
689
744
  @type_setter ||= type ? "#{type}=" : nil
690
745
  end
691
746
 
747
+
748
+ # Key where embedded document is save.
749
+ # By default is the name of relation
750
+ #
751
+ # @return [ String ] the name of key where save
752
+ #
753
+ # @since 3.0.0
754
+ def store_as
755
+ @store_as ||= (self[:store_as].try(:to_s) || name.to_s)
756
+ end
757
+
692
758
  # Are we validating this relation automatically?
693
759
  #
694
760
  # @example Is automatic validation on?
@@ -754,6 +820,18 @@ module Mongoid # :nodoc:
754
820
  !!order
755
821
  end
756
822
 
823
+ # Is this relation touchable?
824
+ #
825
+ # @example Is the relation touchable?
826
+ # metadata.touchable?
827
+ #
828
+ # @return [ true, false ] If the relation can be touched.
829
+ #
830
+ # @since 3.0.0
831
+ def touchable?
832
+ !!self[:touch]
833
+ end
834
+
757
835
  private
758
836
 
759
837
  # Returns the class name for the relation.
@@ -761,11 +839,67 @@ module Mongoid # :nodoc:
761
839
  # @example Get the class name.
762
840
  # metadata.classify
763
841
  #
764
- # @return [ String ] If embedded_in, the camelized, else classified.
842
+ # @return [ String ] The classified name.
765
843
  #
766
844
  # @since 2.0.0.rc.1
767
845
  def classify
768
- macro == :embedded_in ? name.to_s.camelize : name.to_s.classify
846
+ @classify ||= "#{find_module}::#{name.to_s.classify}"
847
+ end
848
+
849
+ # Get the name for the inverse field.
850
+ #
851
+ # @api private
852
+ #
853
+ # @example Get the inverse field name.
854
+ # metadata.determine_inverse_for(:type)
855
+ #
856
+ # @param [ Symbol ] field The inverse field name.
857
+ #
858
+ # @return [ String ] The name of the field.
859
+ #
860
+ # @since 3.0.0
861
+ def determine_inverse_for(field)
862
+ relation.stores_foreign_key? && polymorphic? ? "#{name}_#{field}" : nil
863
+ end
864
+
865
+ # Find the module the class with the specific name is in.
866
+ # This is done by starting at the inverse_class_name's
867
+ # module and stepping down to see where it is defined.
868
+ #
869
+ # @api private
870
+ #
871
+ # @example Find the module.
872
+ # metadata.find_module
873
+ #
874
+ # @return [ String ] The module.
875
+ #
876
+ # @since 3.0.0
877
+ def find_module
878
+ if inverse_class_name.present?
879
+ parts = inverse_class_name.split('::')
880
+ modules = parts.size.times.map { |i| parts.first(i).join('::') }.reverse
881
+ find_from_parts(modules)
882
+ end
883
+ end
884
+
885
+ # Find the modules from a reversed list.
886
+ #
887
+ # @api private
888
+ #
889
+ # @example Find the module from the parts.
890
+ # metadata.find_from_parts([ "Namespace", "Module" ])
891
+ #
892
+ # @param [ Array<String> ] The modules.
893
+ #
894
+ # @return [ String ] The matching module.
895
+ #
896
+ # @since 3.0.0
897
+ def find_from_parts(modules)
898
+ modules.find do |mod|
899
+ ActiveSupport::Inflector.constantize(mod).constants.include?(
900
+ name.to_s.classify.to_sym
901
+ )
902
+ end
769
903
  end
770
904
 
771
905
  # Get the name of the inverse relation in a cyclic relation.
@@ -820,11 +954,7 @@ module Mongoid # :nodoc:
820
954
  return self[:foreign_key].to_s if self[:foreign_key]
821
955
  suffix = relation.foreign_key_suffix
822
956
  if relation.stores_foreign_key?
823
- if relation.macro == :references_and_referenced_in_many
824
- "#{name.to_s.singularize}#{suffix}"
825
- else
826
- "#{name}#{suffix}"
827
- end
957
+ relation.foreign_key(name)
828
958
  else
829
959
  if polymorphic?
830
960
  "#{self[:as]}#{suffix}"
@@ -861,15 +991,55 @@ module Mongoid # :nodoc:
861
991
  #
862
992
  # @since 2.0.0.rc.1
863
993
  def determine_inverse_relation
864
- default = klass.relations[inverse_klass.name.underscore]
994
+ default = foreign_key_match || klass.relations[inverse_klass.name.underscore]
865
995
  return default.name if default
866
- klass.relations.each_pair do |key, meta|
867
- next if meta.versioned? || meta.name == name
868
- if meta.class_name == inverse_class_name
869
- return key.to_sym
996
+ candidates = inverse_relation_candidates
997
+
998
+ if candidates.size > 1
999
+ raise Errors::AmbiguousRelationship.new(
1000
+ klass,
1001
+ inverse_klass,
1002
+ name,
1003
+ candidates
1004
+ )
1005
+ end
1006
+ candidates.first
1007
+ end
1008
+
1009
+ # Return metadata where the foreign key matches the foreign key on this
1010
+ # relation.
1011
+ #
1012
+ # @api private
1013
+ #
1014
+ # @example Return a foreign key match.
1015
+ # meta.foreign_key_match
1016
+ #
1017
+ # @return [ Metadata ] A match, if any.
1018
+ #
1019
+ # @since 2.4.11
1020
+ def foreign_key_match
1021
+ if fk = self[:foreign_key]
1022
+ klass.relations.values.detect do |meta|
1023
+ fk == meta.foreign_key if meta.stores_foreign_key?
870
1024
  end
871
1025
  end
872
- return nil
1026
+ end
1027
+
1028
+ # Get the candidates for inverse relations.
1029
+ #
1030
+ # @api private
1031
+ #
1032
+ # @example Get the candidates.
1033
+ # metadata.inverse_relation_candidates
1034
+ #
1035
+ # @return [ Array<Symbol> ] The candidates.
1036
+ #
1037
+ # @since 3.0.0
1038
+ def inverse_relation_candidates
1039
+ klass.relations.select do |_, meta|
1040
+ next if meta.versioned? || meta.name == name
1041
+ meta.class_name == inverse_class_name
1042
+ end.keys.map(&:to_sym)
873
1043
  end
874
1044
 
875
1045
  # Determine the key for the relation in the attributes.
@@ -881,7 +1051,7 @@ module Mongoid # :nodoc:
881
1051
  #
882
1052
  # @since 2.0.0.rc.1
883
1053
  def determine_key
884
- return name.to_s if relation.embedded?
1054
+ return store_as.to_s if relation.embedded?
885
1055
  relation.stores_foreign_key? ? foreign_key : "_id"
886
1056
  end
887
1057
 
@@ -909,6 +1079,23 @@ module Mongoid # :nodoc:
909
1079
  @inverse_name ||= inverse_klass.name.underscore
910
1080
  end
911
1081
 
1082
+ # For polymorphic children, we need to figure out the inverse from the
1083
+ # actual instance on the other side, since we cannot know the exact class
1084
+ # name to infer it from at load time.
1085
+ #
1086
+ # @example Find the inverses.
1087
+ # metadata.lookup_inverses(other)
1088
+ #
1089
+ # @param [ Document ] : The inverse document.
1090
+ #
1091
+ # @return [ Array<String> ] The inverse names.
1092
+ def lookup_inverses(other)
1093
+ if other
1094
+ matching_metas = other.class.relations.find_all { |key, meta| meta.as == name }
1095
+ matching_metas.map { |meta| meta[1].name }
1096
+ end
1097
+ end
1098
+
912
1099
  # For polymorphic children, we need to figure out the inverse from the
913
1100
  # actual instance on the other side, since we cannot know the exact class
914
1101
  # name to infer it from at load time.
@@ -922,9 +1109,8 @@ module Mongoid # :nodoc:
922
1109
  #
923
1110
  # @since 2.0.0.rc.1
924
1111
  def lookup_inverse(other)
925
- return nil unless other
926
- other.class.relations.each_pair do |key, meta|
927
- return meta.name if meta.as == name
1112
+ if invs = lookup_inverses(other) && invs.count == 1
1113
+ invs.first
928
1114
  end
929
1115
  end
930
1116
  end
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
- module Mongoid # :nodoc:
3
- module Relations #:nodoc:
2
+ module Mongoid
3
+ module Relations
4
4
 
5
5
  # This is the superclass for builders that are in charge of handling
6
6
  # creation, deletion, and updates of documents through that ever so lovely
@@ -57,8 +57,6 @@ module Mongoid # :nodoc:
57
57
 
58
58
  # Convert an id to its appropriate type.
59
59
  #
60
- # @todo Durran: Move this into a common reusable place.
61
- #
62
60
  # @example Convert the id.
63
61
  # builder.convert_id(Person, "4d371b444835d98b8b000010")
64
62
  #
@@ -69,7 +67,7 @@ module Mongoid # :nodoc:
69
67
  #
70
68
  # @since 2.0.0.rc.6
71
69
  def convert_id(klass, id)
72
- BSON::ObjectId.convert(klass, id)
70
+ klass.using_object_ids? ? BSON::ObjectId.mongoize(id) : id
73
71
  end
74
72
  end
75
73
  end
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
- module Mongoid # :nodoc:
3
- module Relations #:nodoc:
2
+ module Mongoid
3
+ module Relations
4
4
 
5
5
  # This is the superclass for one to one relations and defines the common
6
6
  # behaviour or those proxies.
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
- module Mongoid # :nodoc:
3
- module Relations #:nodoc:
2
+ module Mongoid
3
+ module Relations
4
4
 
5
5
  # This module contains the validating logic for options passed to relation
6
6
  # macros.
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
- module Mongoid # :nodoc:
3
- module Relations #:nodoc:
2
+ module Mongoid
3
+ module Relations
4
4
 
5
5
  # This module contains the behaviour for handling polymorphic relational
6
6
  # associations.
@@ -11,7 +11,7 @@ module Mongoid # :nodoc:
11
11
  class_attribute :polymorphic
12
12
  end
13
13
 
14
- module ClassMethods #:nodoc:
14
+ module ClassMethods
15
15
 
16
16
  # Attempts to set up the information needed to handle a polymorphic
17
17
  # relation, if the metadata checks out.
@@ -25,14 +25,14 @@ module Mongoid # :nodoc:
25
25
  #
26
26
  # @since 2.0.0.rc.1
27
27
  def polymorph(metadata)
28
- tap do |klass|
29
- if metadata.polymorphic?
30
- klass.polymorphic = true
31
- if metadata.relation.stores_foreign_key?
32
- field(metadata.inverse_type, :type => String)
33
- end
28
+ if metadata.polymorphic?
29
+ self.polymorphic = true
30
+ if metadata.relation.stores_foreign_key?
31
+ field(metadata.inverse_type, type: String)
32
+ field(metadata.inverse_of_field, type: Symbol)
34
33
  end
35
34
  end
35
+ self
36
36
  end
37
37
  end
38
38
  end
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
- module Mongoid # :nodoc:
3
- module Relations #:nodoc:
2
+ module Mongoid
3
+ module Relations
4
4
 
5
5
  # This class is the superclass for all relation proxy objects, and contains
6
6
  # common behaviour for all of them.
@@ -18,9 +18,9 @@ module Mongoid # :nodoc:
18
18
  attr_accessor :base, :loaded, :metadata, :target
19
19
 
20
20
  # Backwards compatibility with Mongoid beta releases.
21
- delegate :klass, :to => :metadata
22
- delegate :bind_one, :unbind_one, :to => :binding
23
- delegate :collection_name, :to => :base
21
+ delegate :klass, :foreign_key, :inverse_foreign_key, to: :metadata
22
+ delegate :bind_one, :unbind_one, to: :binding
23
+ delegate :collection_name, to: :base
24
24
 
25
25
  # Convenience for setting the target and the metadata properties since
26
26
  # all proxies will need to do this.
@@ -52,6 +52,35 @@ module Mongoid # :nodoc:
52
52
  target
53
53
  end
54
54
 
55
+ # Tell the next persistance operation to store in a specific collection,
56
+ # database or session.
57
+ #
58
+ # @example Save the current document to a different collection.
59
+ # model.with(collection: "secondary").save
60
+ #
61
+ # @example Save the current document to a different database.
62
+ # model.with(database: "secondary").save
63
+ #
64
+ # @example Save the current document to a different session.
65
+ # model.with(session: "replica_set").save
66
+ #
67
+ # @example Save with a combination of options.
68
+ # model.with(session: "sharded", database: "secondary").save
69
+ #
70
+ # @param [ Hash ] options The storage options.
71
+ #
72
+ # @option options [ String, Symbol ] :collection The collection name.
73
+ # @option options [ String, Symbol ] :database The database name.
74
+ # @option options [ String, Symbol ] :session The session name.
75
+ #
76
+ # @return [ Document ] The current document.
77
+ #
78
+ # @since 3.0.0
79
+ def with(options)
80
+ Threaded.set_persistence_options(klass, options)
81
+ self
82
+ end
83
+
55
84
  protected
56
85
 
57
86
  # Get the collection from the root of the hierarchy.
@@ -67,22 +96,6 @@ module Mongoid # :nodoc:
67
96
  root.collection unless root.embedded?
68
97
  end
69
98
 
70
- # Return a new document for the type of class we want to instantiate.
71
- # If the type is provided use that, otherwise the klass from the
72
- # metadata.
73
- #
74
- # @example Get an instantiated document.
75
- # proxy.instantiated(Person)
76
- #
77
- # @param [ Class ] type The type of class to instantiate.
78
- #
79
- # @return [ Document ] The freshly created document.
80
- #
81
- # @since 2.0.0.rc.1
82
- def instantiated(type = nil)
83
- type ? type.new : metadata.klass.new
84
- end
85
-
86
99
  # Takes the supplied document and sets the metadata on it.
87
100
  #
88
101
  # @example Set the metadata.
@@ -132,16 +145,32 @@ module Mongoid # :nodoc:
132
145
  raise Errors::UnsavedDocument.new(base, doc)
133
146
  end
134
147
 
135
- # Get the class of the root document in the hierarchy.
136
- #
137
- # @example Get the root's class.
138
- # proxy.root_class
139
- #
140
- # @return [ Class ] The root class.
141
- #
142
- # @since 2.1.8
143
- def root_class
144
- @root_class ||= base._root.class
148
+ class << self
149
+
150
+ # Get the criteria that is used to eager load a relation of this
151
+ # type.
152
+ #
153
+ # @example Get the eager load criteria.
154
+ # Proxy.eager_load(metadata, criteria)
155
+ #
156
+ # @param [ Metadata ] metadata The relation metadata.
157
+ # @param [ Array<Object> ] ids The ids of the base docs.
158
+ #
159
+ # @return [ Criteria ] The criteria to eager load the relation.
160
+ #
161
+ # @since 2.2.0
162
+ def eager_load_ids(metadata, ids)
163
+ cleared = false
164
+ klass, foreign_key = metadata.klass, metadata.foreign_key
165
+ klass.any_in(foreign_key => ids).each do |doc|
166
+ selector = { foreign_key => doc.send(foreign_key) }
167
+ unless cleared
168
+ IdentityMap.clear_many(klass, selector)
169
+ cleared = true
170
+ end
171
+ yield(doc, foreign_key => doc.send(foreign_key))
172
+ end
173
+ end
145
174
  end
146
175
  end
147
176
  end