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,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 all the behaviour related to accessing relations
6
6
  # through the getters and setters, and how to delegate to builders to
@@ -12,7 +12,7 @@ module Mongoid # :nodoc:
12
12
  # document is nil, then sets the relation on this document.
13
13
  #
14
14
  # @example Build the relation.
15
- # person.build(:addresses, { :id => 1 }, metadata)
15
+ # person.__build__(:addresses, { :id => 1 }, metadata)
16
16
  #
17
17
  # @param [ String, Symbol ] name The name of the relation.
18
18
  # @param [ Hash, BSON::ObjectId ] object The id or attributes to use.
@@ -22,7 +22,7 @@ module Mongoid # :nodoc:
22
22
  # @return [ Proxy ] The relation.
23
23
  #
24
24
  # @since 2.0.0.rc.1
25
- def build(name, object, metadata)
25
+ def __build__(name, object, metadata)
26
26
  relation = create_relation(object, metadata)
27
27
  set_relation(name, relation)
28
28
  end
@@ -74,7 +74,64 @@ module Mongoid # :nodoc:
74
74
  instance_variable_set("@#{name}", relation)
75
75
  end
76
76
 
77
- module ClassMethods #:nodoc:
77
+ private
78
+
79
+ # Is the current code executing without autobuild functionality?
80
+ #
81
+ # @example Is autobuild disabled?
82
+ # document.without_autobuild?
83
+ #
84
+ # @return [ true, false ] If autobuild is disabled.
85
+ #
86
+ # @since 3.0.0
87
+ def without_autobuild?
88
+ Threaded.executing?(:without_autobuild)
89
+ end
90
+
91
+ # Yield to the block with autobuild functionality turned off.
92
+ #
93
+ # @example Execute without autobuild.
94
+ # document.without_autobuild do
95
+ # document.name
96
+ # end
97
+ #
98
+ # @return [ Object ] The result of the yield.
99
+ #
100
+ # @since 3.0.0
101
+ def without_autobuild
102
+ Threaded.begin("without_autobuild")
103
+ yield
104
+ ensure
105
+ Threaded.exit("without_autobuild")
106
+ end
107
+
108
+ module ClassMethods
109
+
110
+ # Adds the existence check for relations.
111
+ #
112
+ # @example Add the existence check.
113
+ # Person.existence_check(:name, meta)
114
+ #
115
+ # @example Check if a relation exists.
116
+ # person = Person.new
117
+ # person.has_game?
118
+ # person.game?
119
+ #
120
+ # @param [ String, Symbol ] name The name of the relation.
121
+ # @param [ Metadata ] The metadata.
122
+ #
123
+ # @return [ Class ] The model being set up.
124
+ #
125
+ # @since 3.0.0
126
+ def existence_check(name, metadata)
127
+ module_eval <<-END
128
+ def #{name}?
129
+ without_autobuild { !#{name}.blank? }
130
+ end
131
+ alias :has_#{name}? :#{name}?
132
+ END
133
+ self
134
+ end
78
135
 
79
136
  # Defines the getter for the relation. Nothing too special here: just
80
137
  # return the instance variable for the relation if it exists or build
@@ -90,22 +147,43 @@ module Mongoid # :nodoc:
90
147
  #
91
148
  # @since 2.0.0.rc.1
92
149
  def getter(name, metadata)
93
- tap do
94
- define_method(name) do |*args|
95
- reload, variable = args.first, "@#{name}"
96
- if instance_variable_defined?(variable) && !reload
97
- instance_variable_get(variable)
98
- else
99
- _building do
100
- _loading do
101
- build(name, attributes[metadata.key], metadata)
102
- end
103
- end
150
+ re_define_method(name) do |*args|
151
+ reload, variable = args.first, "@#{name}"
152
+ value = if instance_variable_defined?(variable) && !reload
153
+ instance_variable_get(variable)
154
+ else
155
+ _building do
156
+ _loading { __build__(name, attributes[metadata.key], metadata) }
104
157
  end
105
158
  end
159
+ if value.nil? && metadata.autobuilding? && !without_autobuild?
160
+ send("build_#{name}")
161
+ else
162
+ value
163
+ end
164
+ end
165
+ self
166
+ end
167
+
168
+ # Defines the getter for the ids of documents in the relation. Should
169
+ # be specify only for referenced many relations.
170
+ #
171
+ # @example Set up the ids getter for the relation.
172
+ # Person.ids_getter("addresses", metadata)
173
+ #
174
+ # @param [ String, Symbol ] name The name of the relation.
175
+ # @param [ Metadata] metadata The metadata for the relation.
176
+ #
177
+ # @return [ Class ] The class being set up.
178
+ def ids_getter(name, metadata)
179
+ ids_method = "#{name.to_s.singularize}_ids"
180
+ re_define_method(ids_method) do
181
+ send(name).only(:id).map(&:id)
106
182
  end
183
+ self
107
184
  end
108
185
 
186
+
109
187
  # Defines the setter for the relation. This does a few things based on
110
188
  # some conditions. If there is an existing association, a target
111
189
  # substitution will take place, otherwise a new relation will be
@@ -121,16 +199,38 @@ module Mongoid # :nodoc:
121
199
  #
122
200
  # @since 2.0.0.rc.1
123
201
  def setter(name, metadata)
124
- tap do
125
- define_method("#{name}=") do |object|
202
+ re_define_method("#{name}=") do |object|
203
+ without_autobuild do
126
204
  if relation_exists?(name) || metadata.many? ||
127
205
  (object.blank? && send(name))
128
206
  set_relation(name, send(name).substitute(object.substitutable))
129
207
  else
130
- build(name, object.substitutable, metadata)
208
+ __build__(name, object.substitutable, metadata)
131
209
  end
132
210
  end
133
211
  end
212
+ self
213
+ end
214
+
215
+ # Defines the setter method that allows you to set documents
216
+ # in this relation by their ids. The defined setter, finds
217
+ # documents with given ids and invokes regular relation setter
218
+ # with found documents. Ids setters should be defined only for
219
+ # referenced many relations.
220
+ #
221
+ # @example Set up the id_setter for the relation.
222
+ # Person.ids_setter("addesses", metadata)
223
+ #
224
+ # @param [ String, Symbol ] name The name of the relation.
225
+ # @param [ Metadata ] metadata The metadata for the relation.
226
+ #
227
+ # @return [ Class ] The class being set up.
228
+ def ids_setter(name, metadata)
229
+ ids_method = "#{name.to_s.singularize}_ids="
230
+ re_define_method(ids_method) do |ids|
231
+ send(metadata.setter, metadata.klass.find(ids))
232
+ end
233
+ self
134
234
  end
135
235
  end
136
236
  end
@@ -1,13 +1,50 @@
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 auto-saving relations in
6
6
  # different collections.
7
7
  module AutoSave
8
8
  extend ActiveSupport::Concern
9
9
 
10
- module ClassMethods #:nodoc:
10
+ included do
11
+ class_attribute :autosaved_relations
12
+ self.autosaved_relations = []
13
+ end
14
+
15
+ # Used to prevent infinite loops in associated autosaves.
16
+ #
17
+ # @example Is the document autosaved?
18
+ # document.autosaved?
19
+ #
20
+ # @return [ true, false ] Has the document already been autosaved?
21
+ #
22
+ # @since 3.0.0
23
+ def autosaved?
24
+ Threaded.autosaved?(self)
25
+ end
26
+
27
+ # Begin the associated autosave.
28
+ #
29
+ # @example Begin autosave.
30
+ # document.begin_autosave
31
+ #
32
+ # @since 3.0.0
33
+ def begin_autosave
34
+ Threaded.begin_autosave(self)
35
+ end
36
+
37
+ # Exit the associated autosave.
38
+ #
39
+ # @example Exit autosave.
40
+ # document.exit_autosave
41
+ #
42
+ # @since 3.0.0
43
+ def exit_autosave
44
+ Threaded.exit_autosave(self)
45
+ end
46
+
47
+ module ClassMethods
11
48
 
12
49
  # Set up the autosave behaviour for references many and references one
13
50
  # relations. When the option is set to true, these relations will get
@@ -21,17 +58,34 @@ module Mongoid # :nodoc:
21
58
  #
22
59
  # @since 2.0.0.rc.1
23
60
  def autosave(metadata)
24
- if metadata.autosave?
25
- set_callback :save, :after do |document|
61
+ if metadata.autosave? && autosavable?(metadata)
62
+ autosaved_relations.push(metadata.name)
63
+ set_callback :save, :after, unless: :autosaved? do |document|
64
+ begin_autosave
26
65
  relation = document.send(metadata.name)
27
66
  if relation
28
67
  (relation.do_or_do_not(:in_memory) || Array.wrap(relation)).each do |doc|
29
68
  doc.save
30
69
  end
31
70
  end
71
+ exit_autosave
32
72
  end
33
73
  end
34
74
  end
75
+
76
+ # Can the autosave be added?
77
+ #
78
+ # @example Can the autosave be added?
79
+ # Person.autosavable?(metadata)
80
+ #
81
+ # @param [ Metadata ] metadata The relation metadata.
82
+ #
83
+ # @return [ true, false ] If the autosave is able to be added.
84
+ #
85
+ # @since 3.0.0
86
+ def autosavable?(metadata)
87
+ !autosaved_relations.include?(metadata.name) && !metadata.embedded?
88
+ end
35
89
  end
36
90
  end
37
91
  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
  # Superclass for all objects that bind relations together.
6
6
  class Binding
@@ -21,6 +21,215 @@ module Mongoid # :nodoc:
21
21
  def initialize(base, target, metadata)
22
22
  @base, @target, @metadata = base, target, metadata
23
23
  end
24
+
25
+ # Execute the provided block inside a binding.
26
+ #
27
+ # @example Execute the binding block.
28
+ # binding.binding do
29
+ # base.foreign_key = 1
30
+ # end
31
+ #
32
+ # @return [ Object ] The result of the yield.
33
+ #
34
+ # @since 3.0.0
35
+ def binding
36
+ unless _binding?
37
+ _binding do
38
+ yield(self) if block_given?
39
+ end
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ # Check if the inverse is properly defined.
46
+ #
47
+ # @api private
48
+ #
49
+ # @example Check the inverse definition.
50
+ # binding.check_inverse!(doc)
51
+ #
52
+ # @param [ Document ] doc The document getting bound.
53
+ #
54
+ # @raise [ Errors::InverseNotFound ] If no inverse found.
55
+ #
56
+ # @since 3.0.0
57
+ def check_inverse!(doc)
58
+ if !metadata.forced_nil_inverse? &&
59
+ !doc.respond_to?(metadata.foreign_key_setter)
60
+ raise Errors::InverseNotFound.new(
61
+ base.class,
62
+ metadata.name,
63
+ doc.class,
64
+ metadata.foreign_key
65
+ )
66
+ end
67
+ end
68
+
69
+ # Check for problems with multiple inverse definitions.
70
+ #
71
+ # @api private
72
+ #
73
+ # @example Check for inverses errors.
74
+ # binding.check_inverses!(doc)
75
+ #
76
+ # @param [ Document ] doc The document to check.
77
+ #
78
+ # @since 3.0.0
79
+ def check_inverses!(doc)
80
+ inverses = metadata.inverses(doc)
81
+ if inverses.count > 1 && base.send(metadata.foreign_key).nil?
82
+ raise Errors::InvalidSetPolymorphicRelation.new(
83
+ metadata.name, base.class.name, target.class.name
84
+ )
85
+ end
86
+ end
87
+
88
+ # Set the id of the related document in the foreign key field on the
89
+ # keyed document.
90
+ #
91
+ # @api private
92
+ #
93
+ # @example Bind the foreign key.
94
+ # binding.bind_foreign_key(post, person.id)
95
+ #
96
+ # @param [ Document ] keyed The document that stores the foreign key.
97
+ # @param [ Object ] id The id of the bound document.
98
+ #
99
+ # @since 3.0.0
100
+ def bind_foreign_key(keyed, id)
101
+ unless keyed.frozen?
102
+ keyed.you_must(metadata.foreign_key_setter, id)
103
+ end
104
+ end
105
+
106
+ # Set the type of the related document on the foreign type field, used
107
+ # when relations are polymorphic.
108
+ #
109
+ # @api private
110
+ #
111
+ # @example Bind the polymorphic type.
112
+ # binding.bind_polymorphic_type(post, "Person")
113
+ #
114
+ # @param [ Document ] typed The document that stores the type field.
115
+ # @param [ String ] name The name of the model.
116
+ #
117
+ # @since 3.0.0
118
+ def bind_polymorphic_type(typed, name)
119
+ if metadata.type
120
+ typed.you_must(metadata.type_setter, name)
121
+ end
122
+ end
123
+
124
+ # Set the type of the related document on the foreign type field, used
125
+ # when relations are polymorphic.
126
+ #
127
+ # @api private
128
+ #
129
+ # @example Bind the polymorphic type.
130
+ # binding.bind_polymorphic_inverse_type(post, "Person")
131
+ #
132
+ # @param [ Document ] typed The document that stores the type field.
133
+ # @param [ String ] name The name of the model.
134
+ #
135
+ # @since 3.0.0
136
+ def bind_polymorphic_inverse_type(typed, name)
137
+ if metadata.inverse_type
138
+ typed.you_must(metadata.inverse_type_setter, name)
139
+ end
140
+ end
141
+
142
+ # Bind the inverse document to the child document so that the in memory
143
+ # instances are the same.
144
+ #
145
+ # @api private
146
+ #
147
+ # @example Bind the inverse.
148
+ # binding.bind_inverse(post, person)
149
+ #
150
+ # @param [ Document ] doc The base document.
151
+ # @param [ Document ] inverse The inverse document.
152
+ #
153
+ # @since 3.0.0
154
+ def bind_inverse(doc, inverse)
155
+ if doc.respond_to?(metadata.inverse_setter)
156
+ doc.you_must(metadata.inverse_setter, inverse)
157
+ end
158
+ end
159
+
160
+ # Bind the inverse of field, when in a polymorphic relation.
161
+ #
162
+ # @api private
163
+ #
164
+ # @example Bind the inverse of field.
165
+ # binding.bind_inverse_of_field(doc)
166
+ #
167
+ # @param [ Document ] doc The document to bind.
168
+ # @param [ String ] name The name of the relation.
169
+ #
170
+ # @since 3.0.0
171
+ def bind_inverse_of_field(doc, name)
172
+ if inverse_metadata = metadata.inverse_metadata(doc)
173
+ if setter = inverse_metadata.inverse_of_field_setter
174
+ doc.you_must(setter, name)
175
+ end
176
+ end
177
+ end
178
+
179
+ # Bind the provided document with the base from the parent relation.
180
+ #
181
+ # @api private
182
+ #
183
+ # @example Bind the document with the base.
184
+ # binding.bind_from_relational_parent(doc)
185
+ #
186
+ # @param [ Document ] doc The document to bind.
187
+ #
188
+ # @since 3.0.0
189
+ def bind_from_relational_parent(doc)
190
+ check_inverse!(doc)
191
+ bind_foreign_key(doc, base.id)
192
+ bind_polymorphic_type(doc, base.class.model_name)
193
+ bind_inverse(doc, base)
194
+ bind_inverse_of_field(doc, metadata.name)
195
+ end
196
+
197
+ # Ensure that the metadata on the base is correct, for the cases
198
+ # where we have multiple belongs to definitions and were are setting
199
+ # different parents in memory in order.
200
+ #
201
+ # @api private
202
+ #
203
+ # @example Set the base metadata.
204
+ # binding.set_base_metadata
205
+ #
206
+ # @return [ true, false ] If the metadata changed.
207
+ #
208
+ # @since 2.4.4
209
+ def set_base_metadata
210
+ inverse_metadata = metadata.inverse_metadata(target)
211
+ if inverse_metadata != metadata && !inverse_metadata.nil?
212
+ base.metadata = inverse_metadata
213
+ end
214
+ end
215
+
216
+ # Bind the provided document with the base from the parent relation.
217
+ #
218
+ # @api private
219
+ #
220
+ # @example Bind the document with the base.
221
+ # unbinding.unbind_from_relational_parent(doc)
222
+ #
223
+ # @param [ Document ] doc The document to unbind.
224
+ #
225
+ # @since 3.0.0
226
+ def unbind_from_relational_parent(doc)
227
+ check_inverse!(doc)
228
+ bind_foreign_key(doc, nil)
229
+ bind_polymorphic_type(doc, nil)
230
+ bind_inverse(doc, nil)
231
+ bind_inverse_of_field(doc, nil)
232
+ end
24
233
  end
25
234
  end
26
235
  end
@@ -1,8 +1,8 @@
1
1
  # encoding: utf-8
2
- module Mongoid # :nodoc:
3
- module Relations #:nodoc:
4
- module Bindings #:nodoc:
5
- module Embedded #:nodoc:
2
+ module Mongoid
3
+ module Relations
4
+ module Bindings
5
+ module Embedded
6
6
 
7
7
  # Binding class for embedded_in relations.
8
8
  class In < Binding
@@ -23,20 +23,17 @@ module Mongoid # :nodoc:
23
23
  # @option options [ true, false ] :binding Are we in build mode?
24
24
  #
25
25
  # @since 2.0.0.rc.1
26
- def bind
26
+ def bind_one
27
27
  base.metadata = metadata.inverse_metadata(target) unless base.metadata
28
28
  base.parentize(target)
29
- unless _binding?
30
- _binding do
31
- if base.embedded_many?
32
- target.do_or_do_not(metadata.inverse(target)).push(base)
33
- else
34
- target.do_or_do_not(metadata.inverse_setter(target), base)
35
- end
29
+ binding do
30
+ if base.embedded_many?
31
+ target.do_or_do_not(metadata.inverse(target)).push(base)
32
+ else
33
+ target.do_or_do_not(metadata.inverse_setter(target), base)
36
34
  end
37
35
  end
38
36
  end
39
- alias :bind_one :bind
40
37
 
41
38
  # Unbinds the base object and the inverse, caused by setting the
42
39
  # reference to nil.
@@ -50,18 +47,15 @@ module Mongoid # :nodoc:
50
47
  # @option options [ true, false ] :continue Do we continue unbinding?
51
48
  #
52
49
  # @since 2.0.0.rc.1
53
- def unbind
54
- unless _binding?
55
- _binding do
56
- if base.embedded_many?
57
- target.do_or_do_not(metadata.inverse(target)).delete(base)
58
- else
59
- target.do_or_do_not(metadata.inverse_setter(target), nil)
60
- end
50
+ def unbind_one
51
+ binding do
52
+ if base.embedded_many?
53
+ target.do_or_do_not(metadata.inverse(target)).delete(base)
54
+ else
55
+ target.do_or_do_not(metadata.inverse_setter(target), nil)
61
56
  end
62
57
  end
63
58
  end
64
- alias :unbind_one :unbind
65
59
  end
66
60
  end
67
61
  end
@@ -1,32 +1,12 @@
1
1
  # encoding: utf-8
2
- module Mongoid # :nodoc:
3
- module Relations #:nodoc:
4
- module Bindings #:nodoc:
5
- module Embedded #:nodoc:
2
+ module Mongoid
3
+ module Relations
4
+ module Bindings
5
+ module Embedded
6
6
 
7
7
  # Binding class for embeds_many relations.
8
8
  class Many < Binding
9
9
 
10
- # Binds the base object to the inverse of the relation. This is so we
11
- # are referenced to the actual objects themselves on both sides.
12
- #
13
- # This case sets the metadata on the inverse object as well as the
14
- # document itself.
15
- #
16
- # @example Bind all the documents.
17
- # person.addresses.bind
18
- # person.addresses = [ Address.new ]
19
- #
20
- # @param [ Hash ] options The binding options.
21
- #
22
- # @option options [ true, false ] :continue Continue binding the inverse.
23
- # @option options [ true, false ] :binding Are we in build mode?
24
- #
25
- # @since 2.0.0.rc.1
26
- def bind
27
- target.each { |doc| bind_one(doc) }
28
- end
29
-
30
10
  # Binds a single document with the inverse relation. Used
31
11
  # specifically when appending to the proxy.
32
12
  #
@@ -42,32 +22,13 @@ module Mongoid # :nodoc:
42
22
  # @since 2.0.0.rc.1
43
23
  def bind_one(doc)
44
24
  doc.parentize(base)
45
- unless _binding?
46
- _binding do
47
- unless metadata.versioned?
48
- doc.do_or_do_not(metadata.inverse_setter(target), base)
49
- end
25
+ binding do
26
+ unless metadata.versioned?
27
+ doc.do_or_do_not(metadata.inverse_setter(target), base)
50
28
  end
51
29
  end
52
30
  end
53
31
 
54
- # Unbinds the base object and the inverse, caused by setting the
55
- # reference to nil.
56
- #
57
- # @example Unbind the documents.
58
- # person.addresses.unbind
59
- # person.addresses = nil
60
- #
61
- # @param [ Hash ] options The binding options.
62
- #
63
- # @option options [ true, false ] :continue Continue binding the inverse.
64
- # @option options [ true, false ] :binding Are we in build mode?
65
- #
66
- # @since 2.0.0.rc.1
67
- def unbind
68
- target.each { |doc| unbind_one(doc) }
69
- end
70
-
71
32
  # Unbind a single document.
72
33
  #
73
34
  # @example Unbind the document.
@@ -80,10 +41,8 @@ module Mongoid # :nodoc:
80
41
  #
81
42
  # @since 2.0.0.rc.1
82
43
  def unbind_one(doc)
83
- unless _binding?
84
- _binding do
85
- doc.do_or_do_not(metadata.inverse_setter(target), nil)
86
- end
44
+ binding do
45
+ doc.do_or_do_not(metadata.inverse_setter(target), nil)
87
46
  end
88
47
  end
89
48
  end
@@ -1,8 +1,8 @@
1
1
  # encoding: utf-8
2
- module Mongoid # :nodoc:
3
- module Relations #:nodoc:
4
- module Bindings #:nodoc:
5
- module Embedded #:nodoc:
2
+ module Mongoid
3
+ module Relations
4
+ module Bindings
5
+ module Embedded
6
6
 
7
7
  # Binding class for embeds_one relations.
8
8
  class One < Binding
@@ -23,15 +23,12 @@ module Mongoid # :nodoc:
23
23
  # @option options [ true, false ] :binding Are we in build mode?
24
24
  #
25
25
  # @since 2.0.0.rc.1
26
- def bind
26
+ def bind_one
27
27
  target.parentize(base)
28
- unless _binding?
29
- _binding do
30
- target.do_or_do_not(metadata.inverse_setter(target), base)
31
- end
28
+ binding do
29
+ target.do_or_do_not(metadata.inverse_setter(target), base)
32
30
  end
33
31
  end
34
- alias :bind_one :bind
35
32
 
36
33
  # Unbinds the base object and the inverse, caused by setting the
37
34
  # reference to nil.
@@ -46,14 +43,11 @@ module Mongoid # :nodoc:
46
43
  # @option options [ true, false ] :binding Are we in build mode?
47
44
  #
48
45
  # @since 2.0.0.rc.1
49
- def unbind
50
- unless _binding?
51
- _binding do
52
- target.do_or_do_not(metadata.inverse_setter(target), nil)
53
- end
46
+ def unbind_one
47
+ binding do
48
+ target.do_or_do_not(metadata.inverse_setter(target), nil)
54
49
  end
55
50
  end
56
- alias :unbind_one :unbind
57
51
  end
58
52
  end
59
53
  end