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,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?
@@ -773,11 +839,67 @@ module Mongoid # :nodoc:
773
839
  # @example Get the class name.
774
840
  # metadata.classify
775
841
  #
776
- # @return [ String ] If embedded_in, the camelized, else classified.
842
+ # @return [ String ] The classified name.
777
843
  #
778
844
  # @since 2.0.0.rc.1
779
845
  def classify
780
- 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
781
903
  end
782
904
 
783
905
  # Get the name of the inverse relation in a cyclic relation.
@@ -832,11 +954,7 @@ module Mongoid # :nodoc:
832
954
  return self[:foreign_key].to_s if self[:foreign_key]
833
955
  suffix = relation.foreign_key_suffix
834
956
  if relation.stores_foreign_key?
835
- if relation.macro == :references_and_referenced_in_many
836
- "#{name.to_s.singularize}#{suffix}"
837
- else
838
- "#{name}#{suffix}"
839
- end
957
+ relation.foreign_key(name)
840
958
  else
841
959
  if polymorphic?
842
960
  "#{self[:as]}#{suffix}"
@@ -875,13 +993,17 @@ module Mongoid # :nodoc:
875
993
  def determine_inverse_relation
876
994
  default = foreign_key_match || klass.relations[inverse_klass.name.underscore]
877
995
  return default.name if default
878
- klass.relations.each_pair do |key, meta|
879
- next if meta.versioned? || meta.name == name
880
- if meta.class_name == inverse_class_name
881
- return key.to_sym
882
- end
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
+ )
883
1005
  end
884
- return nil
1006
+ candidates.first
885
1007
  end
886
1008
 
887
1009
  # Return metadata where the foreign key matches the foreign key on this
@@ -903,6 +1025,23 @@ module Mongoid # :nodoc:
903
1025
  end
904
1026
  end
905
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)
1043
+ end
1044
+
906
1045
  # Determine the key for the relation in the attributes.
907
1046
  #
908
1047
  # @example Get the key.
@@ -912,7 +1051,7 @@ module Mongoid # :nodoc:
912
1051
  #
913
1052
  # @since 2.0.0.rc.1
914
1053
  def determine_key
915
- return name.to_s if relation.embedded?
1054
+ return store_as.to_s if relation.embedded?
916
1055
  relation.stores_foreign_key? ? foreign_key : "_id"
917
1056
  end
918
1057
 
@@ -940,6 +1079,23 @@ module Mongoid # :nodoc:
940
1079
  @inverse_name ||= inverse_klass.name.underscore
941
1080
  end
942
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
+
943
1099
  # For polymorphic children, we need to figure out the inverse from the
944
1100
  # actual instance on the other side, since we cannot know the exact class
945
1101
  # name to infer it from at load time.
@@ -953,9 +1109,8 @@ module Mongoid # :nodoc:
953
1109
  #
954
1110
  # @since 2.0.0.rc.1
955
1111
  def lookup_inverse(other)
956
- return nil unless other
957
- other.class.relations.each_pair do |key, meta|
958
- return meta.name if meta.as == name
1112
+ if invs = lookup_inverses(other) && invs.count == 1
1113
+ invs.first
959
1114
  end
960
1115
  end
961
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