mongoid-multi-db 3.0.0

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 (276) hide show
  1. data/CHANGELOG.md +615 -0
  2. data/LICENSE +20 -0
  3. data/README.md +62 -0
  4. data/Rakefile +49 -0
  5. data/lib/config/locales/bg.yml +54 -0
  6. data/lib/config/locales/de.yml +54 -0
  7. data/lib/config/locales/en-GB.yml +55 -0
  8. data/lib/config/locales/en.yml +55 -0
  9. data/lib/config/locales/es.yml +52 -0
  10. data/lib/config/locales/fr.yml +55 -0
  11. data/lib/config/locales/hi.yml +46 -0
  12. data/lib/config/locales/hu.yml +57 -0
  13. data/lib/config/locales/id.yml +55 -0
  14. data/lib/config/locales/it.yml +52 -0
  15. data/lib/config/locales/ja.yml +50 -0
  16. data/lib/config/locales/kr.yml +47 -0
  17. data/lib/config/locales/nl.yml +52 -0
  18. data/lib/config/locales/pl.yml +52 -0
  19. data/lib/config/locales/pt-BR.yml +53 -0
  20. data/lib/config/locales/pt.yml +53 -0
  21. data/lib/config/locales/ro.yml +59 -0
  22. data/lib/config/locales/ru.yml +54 -0
  23. data/lib/config/locales/sv.yml +53 -0
  24. data/lib/config/locales/vi.yml +55 -0
  25. data/lib/config/locales/zh-CN.yml +46 -0
  26. data/lib/mongoid.rb +148 -0
  27. data/lib/mongoid/atomic.rb +230 -0
  28. data/lib/mongoid/atomic/modifiers.rb +243 -0
  29. data/lib/mongoid/atomic/paths.rb +3 -0
  30. data/lib/mongoid/atomic/paths/embedded.rb +43 -0
  31. data/lib/mongoid/atomic/paths/embedded/many.rb +44 -0
  32. data/lib/mongoid/atomic/paths/embedded/one.rb +43 -0
  33. data/lib/mongoid/atomic/paths/root.rb +40 -0
  34. data/lib/mongoid/attributes.rb +234 -0
  35. data/lib/mongoid/attributes/processing.rb +146 -0
  36. data/lib/mongoid/callbacks.rb +135 -0
  37. data/lib/mongoid/collection.rb +153 -0
  38. data/lib/mongoid/collection_proxy.rb +59 -0
  39. data/lib/mongoid/collections.rb +120 -0
  40. data/lib/mongoid/collections/master.rb +45 -0
  41. data/lib/mongoid/collections/operations.rb +44 -0
  42. data/lib/mongoid/collections/retry.rb +46 -0
  43. data/lib/mongoid/components.rb +96 -0
  44. data/lib/mongoid/config.rb +347 -0
  45. data/lib/mongoid/config/database.rb +186 -0
  46. data/lib/mongoid/config/replset_database.rb +82 -0
  47. data/lib/mongoid/connection_proxy.rb +30 -0
  48. data/lib/mongoid/contexts.rb +25 -0
  49. data/lib/mongoid/contexts/enumerable.rb +288 -0
  50. data/lib/mongoid/contexts/enumerable/sort.rb +43 -0
  51. data/lib/mongoid/contexts/mongo.rb +409 -0
  52. data/lib/mongoid/copyable.rb +48 -0
  53. data/lib/mongoid/criteria.rb +418 -0
  54. data/lib/mongoid/criterion/builder.rb +34 -0
  55. data/lib/mongoid/criterion/complex.rb +84 -0
  56. data/lib/mongoid/criterion/creational.rb +34 -0
  57. data/lib/mongoid/criterion/exclusion.rb +108 -0
  58. data/lib/mongoid/criterion/inclusion.rb +305 -0
  59. data/lib/mongoid/criterion/inspection.rb +22 -0
  60. data/lib/mongoid/criterion/optional.rb +232 -0
  61. data/lib/mongoid/criterion/selector.rb +153 -0
  62. data/lib/mongoid/cursor.rb +86 -0
  63. data/lib/mongoid/database_proxy.rb +97 -0
  64. data/lib/mongoid/default_scope.rb +36 -0
  65. data/lib/mongoid/dirty.rb +110 -0
  66. data/lib/mongoid/document.rb +280 -0
  67. data/lib/mongoid/errors.rb +17 -0
  68. data/lib/mongoid/errors/callback.rb +26 -0
  69. data/lib/mongoid/errors/document_not_found.rb +28 -0
  70. data/lib/mongoid/errors/eager_load.rb +25 -0
  71. data/lib/mongoid/errors/invalid_collection.rb +18 -0
  72. data/lib/mongoid/errors/invalid_database.rb +19 -0
  73. data/lib/mongoid/errors/invalid_field.rb +18 -0
  74. data/lib/mongoid/errors/invalid_find.rb +19 -0
  75. data/lib/mongoid/errors/invalid_options.rb +28 -0
  76. data/lib/mongoid/errors/invalid_time.rb +25 -0
  77. data/lib/mongoid/errors/invalid_type.rb +25 -0
  78. data/lib/mongoid/errors/mixed_relations.rb +37 -0
  79. data/lib/mongoid/errors/mongoid_error.rb +26 -0
  80. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +20 -0
  81. data/lib/mongoid/errors/unsaved_document.rb +23 -0
  82. data/lib/mongoid/errors/unsupported_version.rb +20 -0
  83. data/lib/mongoid/errors/validations.rb +23 -0
  84. data/lib/mongoid/extensions.rb +82 -0
  85. data/lib/mongoid/extensions/array/deletion.rb +29 -0
  86. data/lib/mongoid/extensions/false_class/equality.rb +26 -0
  87. data/lib/mongoid/extensions/hash/criteria_helpers.rb +45 -0
  88. data/lib/mongoid/extensions/hash/scoping.rb +25 -0
  89. data/lib/mongoid/extensions/integer/checks.rb +23 -0
  90. data/lib/mongoid/extensions/nil/collectionization.rb +23 -0
  91. data/lib/mongoid/extensions/object/checks.rb +29 -0
  92. data/lib/mongoid/extensions/object/reflections.rb +48 -0
  93. data/lib/mongoid/extensions/object/substitutable.rb +15 -0
  94. data/lib/mongoid/extensions/object/yoda.rb +44 -0
  95. data/lib/mongoid/extensions/object_id/conversions.rb +60 -0
  96. data/lib/mongoid/extensions/proc/scoping.rb +25 -0
  97. data/lib/mongoid/extensions/string/checks.rb +36 -0
  98. data/lib/mongoid/extensions/string/conversions.rb +22 -0
  99. data/lib/mongoid/extensions/string/inflections.rb +118 -0
  100. data/lib/mongoid/extensions/symbol/checks.rb +23 -0
  101. data/lib/mongoid/extensions/symbol/inflections.rb +66 -0
  102. data/lib/mongoid/extensions/true_class/equality.rb +26 -0
  103. data/lib/mongoid/extras.rb +31 -0
  104. data/lib/mongoid/factory.rb +46 -0
  105. data/lib/mongoid/fields.rb +332 -0
  106. data/lib/mongoid/fields/mappings.rb +41 -0
  107. data/lib/mongoid/fields/serializable.rb +201 -0
  108. data/lib/mongoid/fields/serializable/array.rb +49 -0
  109. data/lib/mongoid/fields/serializable/big_decimal.rb +42 -0
  110. data/lib/mongoid/fields/serializable/bignum.rb +10 -0
  111. data/lib/mongoid/fields/serializable/binary.rb +11 -0
  112. data/lib/mongoid/fields/serializable/boolean.rb +43 -0
  113. data/lib/mongoid/fields/serializable/date.rb +51 -0
  114. data/lib/mongoid/fields/serializable/date_time.rb +28 -0
  115. data/lib/mongoid/fields/serializable/fixnum.rb +10 -0
  116. data/lib/mongoid/fields/serializable/float.rb +32 -0
  117. data/lib/mongoid/fields/serializable/foreign_keys/array.rb +42 -0
  118. data/lib/mongoid/fields/serializable/foreign_keys/object.rb +47 -0
  119. data/lib/mongoid/fields/serializable/hash.rb +11 -0
  120. data/lib/mongoid/fields/serializable/integer.rb +44 -0
  121. data/lib/mongoid/fields/serializable/localized.rb +41 -0
  122. data/lib/mongoid/fields/serializable/nil_class.rb +38 -0
  123. data/lib/mongoid/fields/serializable/object.rb +11 -0
  124. data/lib/mongoid/fields/serializable/object_id.rb +31 -0
  125. data/lib/mongoid/fields/serializable/range.rb +42 -0
  126. data/lib/mongoid/fields/serializable/set.rb +42 -0
  127. data/lib/mongoid/fields/serializable/string.rb +27 -0
  128. data/lib/mongoid/fields/serializable/symbol.rb +27 -0
  129. data/lib/mongoid/fields/serializable/time.rb +23 -0
  130. data/lib/mongoid/fields/serializable/time_with_zone.rb +23 -0
  131. data/lib/mongoid/fields/serializable/timekeeping.rb +106 -0
  132. data/lib/mongoid/finders.rb +152 -0
  133. data/lib/mongoid/hierarchy.rb +120 -0
  134. data/lib/mongoid/identity.rb +92 -0
  135. data/lib/mongoid/identity_map.rb +119 -0
  136. data/lib/mongoid/indexes.rb +54 -0
  137. data/lib/mongoid/inspection.rb +54 -0
  138. data/lib/mongoid/javascript.rb +20 -0
  139. data/lib/mongoid/javascript/functions.yml +63 -0
  140. data/lib/mongoid/json.rb +16 -0
  141. data/lib/mongoid/keys.rb +144 -0
  142. data/lib/mongoid/logger.rb +39 -0
  143. data/lib/mongoid/matchers.rb +32 -0
  144. data/lib/mongoid/matchers/all.rb +21 -0
  145. data/lib/mongoid/matchers/and.rb +30 -0
  146. data/lib/mongoid/matchers/default.rb +70 -0
  147. data/lib/mongoid/matchers/exists.rb +23 -0
  148. data/lib/mongoid/matchers/gt.rb +21 -0
  149. data/lib/mongoid/matchers/gte.rb +21 -0
  150. data/lib/mongoid/matchers/in.rb +21 -0
  151. data/lib/mongoid/matchers/lt.rb +21 -0
  152. data/lib/mongoid/matchers/lte.rb +21 -0
  153. data/lib/mongoid/matchers/ne.rb +21 -0
  154. data/lib/mongoid/matchers/nin.rb +21 -0
  155. data/lib/mongoid/matchers/or.rb +33 -0
  156. data/lib/mongoid/matchers/size.rb +21 -0
  157. data/lib/mongoid/matchers/strategies.rb +93 -0
  158. data/lib/mongoid/multi_database.rb +31 -0
  159. data/lib/mongoid/multi_parameter_attributes.rb +106 -0
  160. data/lib/mongoid/named_scope.rb +146 -0
  161. data/lib/mongoid/nested_attributes.rb +54 -0
  162. data/lib/mongoid/observer.rb +170 -0
  163. data/lib/mongoid/paranoia.rb +158 -0
  164. data/lib/mongoid/persistence.rb +264 -0
  165. data/lib/mongoid/persistence/atomic.rb +223 -0
  166. data/lib/mongoid/persistence/atomic/add_to_set.rb +35 -0
  167. data/lib/mongoid/persistence/atomic/bit.rb +37 -0
  168. data/lib/mongoid/persistence/atomic/inc.rb +31 -0
  169. data/lib/mongoid/persistence/atomic/operation.rb +85 -0
  170. data/lib/mongoid/persistence/atomic/pop.rb +34 -0
  171. data/lib/mongoid/persistence/atomic/pull.rb +34 -0
  172. data/lib/mongoid/persistence/atomic/pull_all.rb +34 -0
  173. data/lib/mongoid/persistence/atomic/push.rb +31 -0
  174. data/lib/mongoid/persistence/atomic/push_all.rb +31 -0
  175. data/lib/mongoid/persistence/atomic/rename.rb +31 -0
  176. data/lib/mongoid/persistence/atomic/sets.rb +30 -0
  177. data/lib/mongoid/persistence/atomic/unset.rb +28 -0
  178. data/lib/mongoid/persistence/deletion.rb +32 -0
  179. data/lib/mongoid/persistence/insertion.rb +41 -0
  180. data/lib/mongoid/persistence/modification.rb +37 -0
  181. data/lib/mongoid/persistence/operations.rb +211 -0
  182. data/lib/mongoid/persistence/operations/embedded/insert.rb +42 -0
  183. data/lib/mongoid/persistence/operations/embedded/remove.rb +40 -0
  184. data/lib/mongoid/persistence/operations/insert.rb +34 -0
  185. data/lib/mongoid/persistence/operations/remove.rb +33 -0
  186. data/lib/mongoid/persistence/operations/update.rb +64 -0
  187. data/lib/mongoid/railtie.rb +126 -0
  188. data/lib/mongoid/railties/database.rake +182 -0
  189. data/lib/mongoid/railties/document.rb +12 -0
  190. data/lib/mongoid/relations.rb +144 -0
  191. data/lib/mongoid/relations/accessors.rb +138 -0
  192. data/lib/mongoid/relations/auto_save.rb +38 -0
  193. data/lib/mongoid/relations/binding.rb +26 -0
  194. data/lib/mongoid/relations/bindings.rb +9 -0
  195. data/lib/mongoid/relations/bindings/embedded/in.rb +69 -0
  196. data/lib/mongoid/relations/bindings/embedded/many.rb +93 -0
  197. data/lib/mongoid/relations/bindings/embedded/one.rb +61 -0
  198. data/lib/mongoid/relations/bindings/referenced/in.rb +76 -0
  199. data/lib/mongoid/relations/bindings/referenced/many.rb +54 -0
  200. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +51 -0
  201. data/lib/mongoid/relations/bindings/referenced/one.rb +58 -0
  202. data/lib/mongoid/relations/builder.rb +57 -0
  203. data/lib/mongoid/relations/builders.rb +83 -0
  204. data/lib/mongoid/relations/builders/embedded/in.rb +29 -0
  205. data/lib/mongoid/relations/builders/embedded/many.rb +40 -0
  206. data/lib/mongoid/relations/builders/embedded/one.rb +30 -0
  207. data/lib/mongoid/relations/builders/nested_attributes/many.rb +110 -0
  208. data/lib/mongoid/relations/builders/nested_attributes/one.rb +135 -0
  209. data/lib/mongoid/relations/builders/referenced/in.rb +26 -0
  210. data/lib/mongoid/relations/builders/referenced/many.rb +27 -0
  211. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +38 -0
  212. data/lib/mongoid/relations/builders/referenced/one.rb +26 -0
  213. data/lib/mongoid/relations/cascading.rb +56 -0
  214. data/lib/mongoid/relations/cascading/delete.rb +19 -0
  215. data/lib/mongoid/relations/cascading/destroy.rb +26 -0
  216. data/lib/mongoid/relations/cascading/nullify.rb +18 -0
  217. data/lib/mongoid/relations/cascading/strategy.rb +26 -0
  218. data/lib/mongoid/relations/constraint.rb +42 -0
  219. data/lib/mongoid/relations/conversions.rb +35 -0
  220. data/lib/mongoid/relations/cyclic.rb +103 -0
  221. data/lib/mongoid/relations/embedded/atomic.rb +89 -0
  222. data/lib/mongoid/relations/embedded/atomic/operation.rb +63 -0
  223. data/lib/mongoid/relations/embedded/atomic/pull.rb +65 -0
  224. data/lib/mongoid/relations/embedded/atomic/push_all.rb +59 -0
  225. data/lib/mongoid/relations/embedded/atomic/set.rb +61 -0
  226. data/lib/mongoid/relations/embedded/atomic/unset.rb +41 -0
  227. data/lib/mongoid/relations/embedded/in.rb +220 -0
  228. data/lib/mongoid/relations/embedded/many.rb +560 -0
  229. data/lib/mongoid/relations/embedded/one.rb +206 -0
  230. data/lib/mongoid/relations/embedded/sort.rb +31 -0
  231. data/lib/mongoid/relations/macros.rb +310 -0
  232. data/lib/mongoid/relations/many.rb +135 -0
  233. data/lib/mongoid/relations/metadata.rb +919 -0
  234. data/lib/mongoid/relations/nested_builder.rb +75 -0
  235. data/lib/mongoid/relations/one.rb +36 -0
  236. data/lib/mongoid/relations/options.rb +47 -0
  237. data/lib/mongoid/relations/polymorphic.rb +40 -0
  238. data/lib/mongoid/relations/proxy.rb +145 -0
  239. data/lib/mongoid/relations/referenced/batch.rb +72 -0
  240. data/lib/mongoid/relations/referenced/batch/insert.rb +57 -0
  241. data/lib/mongoid/relations/referenced/in.rb +262 -0
  242. data/lib/mongoid/relations/referenced/many.rb +623 -0
  243. data/lib/mongoid/relations/referenced/many_to_many.rb +396 -0
  244. data/lib/mongoid/relations/referenced/one.rb +272 -0
  245. data/lib/mongoid/relations/reflections.rb +62 -0
  246. data/lib/mongoid/relations/synchronization.rb +153 -0
  247. data/lib/mongoid/relations/targets.rb +2 -0
  248. data/lib/mongoid/relations/targets/enumerable.rb +372 -0
  249. data/lib/mongoid/reloading.rb +91 -0
  250. data/lib/mongoid/safety.rb +105 -0
  251. data/lib/mongoid/scope.rb +31 -0
  252. data/lib/mongoid/serialization.rb +134 -0
  253. data/lib/mongoid/sharding.rb +61 -0
  254. data/lib/mongoid/state.rb +97 -0
  255. data/lib/mongoid/threaded.rb +530 -0
  256. data/lib/mongoid/threaded/lifecycle.rb +192 -0
  257. data/lib/mongoid/timestamps.rb +15 -0
  258. data/lib/mongoid/timestamps/created.rb +24 -0
  259. data/lib/mongoid/timestamps/timeless.rb +50 -0
  260. data/lib/mongoid/timestamps/updated.rb +26 -0
  261. data/lib/mongoid/validations.rb +140 -0
  262. data/lib/mongoid/validations/associated.rb +46 -0
  263. data/lib/mongoid/validations/uniqueness.rb +145 -0
  264. data/lib/mongoid/version.rb +4 -0
  265. data/lib/mongoid/versioning.rb +185 -0
  266. data/lib/rack/mongoid.rb +2 -0
  267. data/lib/rack/mongoid/middleware/identity_map.rb +38 -0
  268. data/lib/rails/generators/mongoid/config/config_generator.rb +25 -0
  269. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +20 -0
  270. data/lib/rails/generators/mongoid/model/model_generator.rb +24 -0
  271. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +19 -0
  272. data/lib/rails/generators/mongoid/observer/observer_generator.rb +17 -0
  273. data/lib/rails/generators/mongoid/observer/templates/observer.rb.tt +4 -0
  274. data/lib/rails/generators/mongoid_generator.rb +70 -0
  275. data/lib/rails/mongoid.rb +91 -0
  276. metadata +465 -0
@@ -0,0 +1,206 @@
1
+ # encoding: utf-8
2
+ module Mongoid # :nodoc:
3
+ module Relations #:nodoc:
4
+ module Embedded #:nodoc:
5
+
6
+ # This class defines the behaviour needed for embedded one to one
7
+ # relations.
8
+ class One < Relations::One
9
+
10
+ # Instantiate a new embeds_one relation.
11
+ #
12
+ # @example Create the new proxy.
13
+ # One.new(person, name, metadata)
14
+ #
15
+ # @param [ Document ] base The document this relation hangs off of.
16
+ # @param [ Document ] target The child document in the relation.
17
+ # @param [ Metadata ] metadata The relation's metadata
18
+ def initialize(base, target, metadata)
19
+ init(base, target, metadata) do
20
+ characterize_one(target)
21
+ bind_one
22
+ target.save if persistable?
23
+ end
24
+ end
25
+
26
+ # Substitutes the supplied target documents for the existing document
27
+ # in the relation.
28
+ #
29
+ # @example Substitute the new document.
30
+ # person.name.substitute(new_name)
31
+ #
32
+ # @param [ Document ] other A document to replace the target.
33
+ #
34
+ # @return [ Document, nil ] The relation or nil.
35
+ #
36
+ # @since 2.0.0.rc.1
37
+ def substitute(replacement)
38
+ tap do |proxy|
39
+ if _assigning?
40
+ base.atomic_unsets.push(proxy.atomic_path)
41
+ else
42
+ proxy.delete if persistable?
43
+ end
44
+ proxy.unbind_one
45
+ return nil unless replacement
46
+ proxy.target = replacement
47
+ proxy.bind_one
48
+ end
49
+ end
50
+
51
+ private
52
+
53
+ # Instantiate the binding associated with this relation.
54
+ #
55
+ # @example Get the binding.
56
+ # relation.binding([ address ])
57
+ #
58
+ # @param [ Document ] new_target The new document to bind with.
59
+ #
60
+ # @return [ Binding ] The relation's binding.
61
+ #
62
+ # @since 2.0.0.rc.1
63
+ def binding
64
+ Bindings::Embedded::One.new(base, target, metadata)
65
+ end
66
+
67
+ # Are we able to persist this relation?
68
+ #
69
+ # @example Can we persist the relation?
70
+ # relation.persistable?
71
+ #
72
+ # @return [ true, false ] If the relation is persistable.
73
+ #
74
+ # @since 2.1.0
75
+ def persistable?
76
+ base.persisted? && !_binding? && !_building? && !_assigning?
77
+ end
78
+
79
+ class << self
80
+
81
+ # Return the builder that is responsible for generating the documents
82
+ # that will be used by this relation.
83
+ #
84
+ # @example Get the builder.
85
+ # Embedded::One.builder(meta, object, person)
86
+ #
87
+ # @param [ Document ] base The base document.
88
+ # @param [ Metadata ] meta The metadata of the relation.
89
+ # @param [ Document, Hash ] object A document or attributes to build with.
90
+ #
91
+ # @return [ Builder ] A newly instantiated builder object.
92
+ #
93
+ # @since 2.0.0.rc.1
94
+ def builder(base, meta, object)
95
+ Builders::Embedded::One.new(base, meta, object)
96
+ end
97
+
98
+ # Returns true if the relation is an embedded one. In this case
99
+ # always true.
100
+ #
101
+ # @example Is this relation embedded?
102
+ # Embedded::One.embedded?
103
+ #
104
+ # @return [ true ] true.
105
+ #
106
+ # @since 2.0.0.rc.1
107
+ def embedded?
108
+ true
109
+ end
110
+
111
+ # Returns the macro for this relation. Used mostly as a helper in
112
+ # reflection.
113
+ #
114
+ # @example Get the macro.
115
+ # Mongoid::Relations::Embedded::One.macro
116
+ #
117
+ # @return [ Symbol ] :embeds_one.
118
+ #
119
+ # @since 2.0.0.rc.1
120
+ def macro
121
+ :embeds_one
122
+ end
123
+
124
+ # Return the nested builder that is responsible for generating
125
+ # the documents that will be used by this relation.
126
+ #
127
+ # @example Get the builder.
128
+ # NestedAttributes::One.builder(attributes, options)
129
+ #
130
+ # @param [ Metadata ] metadata The relation metadata.
131
+ # @param [ Hash ] attributes The attributes to build with.
132
+ # @param [ Hash ] options The options for the builder.
133
+ #
134
+ # @option options [ true, false ] :allow_destroy Can documents be
135
+ # deleted?
136
+ # @option options [ Integer ] :limit Max number of documents to
137
+ # create at once.
138
+ # @option options [ Proc, Symbol ] :reject_if If documents match this
139
+ # option then they are ignored.
140
+ # @option options [ true, false ] :update_only Only existing documents
141
+ # can be modified.
142
+ #
143
+ # @return [ Builder ] A newly instantiated nested builder object.
144
+ #
145
+ # @since 2.0.0.rc.1
146
+ def nested_builder(metadata, attributes, options)
147
+ Builders::NestedAttributes::One.new(metadata, attributes, options)
148
+ end
149
+
150
+ # Get the path calculator for the supplied document.
151
+ #
152
+ # @example Get the path calculator.
153
+ # Proxy.path(document)
154
+ #
155
+ # @param [ Document ] document The document to calculate on.
156
+ #
157
+ # @return [ Mongoid::Atomic::Paths::Embedded::One ]
158
+ # The embedded one atomic path calculator.
159
+ #
160
+ # @since 2.1.0
161
+ def path(document)
162
+ Mongoid::Atomic::Paths::Embedded::One.new(document)
163
+ end
164
+
165
+ # Tells the caller if this relation is one that stores the foreign
166
+ # key on its own objects.
167
+ #
168
+ # @example Does this relation store a foreign key?
169
+ # Embedded::One.stores_foreign_key?
170
+ #
171
+ # @return [ false ] false.
172
+ #
173
+ # @since 2.0.0.rc.1
174
+ def stores_foreign_key?
175
+ false
176
+ end
177
+
178
+ # Get the valid options allowed with this relation.
179
+ #
180
+ # @example Get the valid options.
181
+ # Relation.valid_options
182
+ #
183
+ # @return [ Array<Symbol> ] The valid options.
184
+ #
185
+ # @since 2.1.0
186
+ def valid_options
187
+ [ :as, :cascade_callbacks, :cyclic ]
188
+ end
189
+
190
+ # Get the default validation setting for the relation. Determines if
191
+ # by default a validates associated will occur.
192
+ #
193
+ # @example Get the validation default.
194
+ # Proxy.validation_default
195
+ #
196
+ # @return [ true, false ] The validation default.
197
+ #
198
+ # @since 2.1.9
199
+ def validation_default
200
+ true
201
+ end
202
+ end
203
+ end
204
+ end
205
+ end
206
+ end
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+ module Mongoid # :nodoc:
3
+ module Relations #:nodoc:
4
+ module Embedded #:nodoc:
5
+
6
+ # This module handles embedded associations sorting
7
+ # Since mongodb doesn't have virtual collection for embedded docs yet
8
+ # (see https://jira.mongodb.org/browse/SERVER-142 for details)
9
+ # Sorting implemented in ruby
10
+ # This can be a performance killer on collections with many embedded documents
11
+ module Sort
12
+
13
+ # Sorts documents
14
+ #
15
+ # @param [ Array<Documents> ] documents array of documents
16
+ # @param [ Mongoid::Relations::Metadata ] metadata association metadata
17
+ def sort_documents!(documents, metadata)
18
+ sort_options = Criteria.new(metadata.klass).order_by(metadata.order).options[:sort]
19
+
20
+ docs = documents.sort_by do |document|
21
+ sort_options.map do |key, direction|
22
+ Contexts::Enumerable::Sort.new(document.read_attribute(key), direction)
23
+ end
24
+ end
25
+ documents.replace(docs)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+
@@ -0,0 +1,310 @@
1
+ # encoding: utf-8
2
+ module Mongoid # :nodoc:
3
+ module Relations #:nodoc:
4
+
5
+ # This module contains the core macros for defining relations between
6
+ # documents. They can be either embedded or referenced (relational).
7
+ module Macros
8
+ extend ActiveSupport::Concern
9
+
10
+ included do
11
+ class_attribute :embedded, :instance_reader => false
12
+ class_attribute :relations
13
+ self.embedded = false
14
+ self.relations = {}
15
+ end
16
+
17
+ # This is convenience for librarys still on the old API.
18
+ #
19
+ # @example Get the associations.
20
+ # person.associations
21
+ #
22
+ # @return [ Hash ] The relations.
23
+ #
24
+ # @since 2.3.1
25
+ def associations
26
+ self.relations
27
+ end
28
+
29
+ module ClassMethods #:nodoc:
30
+
31
+ # Adds the relation back to the parent document. This macro is
32
+ # necessary to set the references from the child back to the parent
33
+ # document. If a child does not define this relation calling
34
+ # persistence methods on the child object will cause a save to fail.
35
+ #
36
+ # @example Define the relation.
37
+ #
38
+ # class Person
39
+ # include Mongoid::Document
40
+ # embeds_many :addresses
41
+ # end
42
+ #
43
+ # class Address
44
+ # include Mongoid::Document
45
+ # embedded_in :person
46
+ # end
47
+ #
48
+ # @param [ Symbol ] name The name of the relation.
49
+ # @param [ Hash ] options The relation options.
50
+ # @param [ Proc ] block Optional block for defining extensions.
51
+ def embedded_in(name, options = {}, &block)
52
+ characterize(name, Embedded::In, options, &block).tap do |meta|
53
+ self.embedded = true
54
+ relate(name, meta)
55
+ end
56
+ end
57
+
58
+ # Adds the relation from a parent document to its children. The name
59
+ # of the relation needs to be a pluralized form of the child class
60
+ # name.
61
+ #
62
+ # @example Define the relation.
63
+ #
64
+ # class Person
65
+ # include Mongoid::Document
66
+ # embeds_many :addresses
67
+ # end
68
+ #
69
+ # class Address
70
+ # include Mongoid::Document
71
+ # embedded_in :person
72
+ # end
73
+ #
74
+ # @param [ Symbol ] name The name of the relation.
75
+ # @param [ Hash ] options The relation options.
76
+ # @param [ Proc ] block Optional block for defining extensions.
77
+ def embeds_many(name, options = {}, &block)
78
+ characterize(name, Embedded::Many, options, &block).tap do |meta|
79
+ relate(name, meta)
80
+ validates_relation(meta)
81
+ end
82
+ end
83
+
84
+ # Adds the relation from a parent document to its child. The name
85
+ # of the relation needs to be a singular form of the child class
86
+ # name.
87
+ #
88
+ # @example Define the relation.
89
+ #
90
+ # class Person
91
+ # include Mongoid::Document
92
+ # embeds_one :name
93
+ # end
94
+ #
95
+ # class Name
96
+ # include Mongoid::Document
97
+ # embedded_in :person
98
+ # end
99
+ #
100
+ # @param [ Symbol ] name The name of the relation.
101
+ # @param [ Hash ] options The relation options.
102
+ # @param [ Proc ] block Optional block for defining extensions.
103
+ def embeds_one(name, options = {}, &block)
104
+ characterize(name, Embedded::One, options, &block).tap do |meta|
105
+ relate(name, meta)
106
+ builder(name, meta).creator(name)
107
+ validates_relation(meta)
108
+ end
109
+ end
110
+
111
+ # Adds a relational association from the child Document to a Document in
112
+ # another database or collection.
113
+ #
114
+ # @example Define the relation.
115
+ #
116
+ # class Game
117
+ # include Mongoid::Document
118
+ # belongs_to :person
119
+ # end
120
+ #
121
+ # class Person
122
+ # include Mongoid::Document
123
+ # has_one :game
124
+ # end
125
+ #
126
+ # @param [ Symbol ] name The name of the relation.
127
+ # @param [ Hash ] options The relation options.
128
+ # @param [ Proc ] block Optional block for defining extensions.
129
+ def belongs_to(name, options = {}, &block)
130
+ characterize(name, Referenced::In, options, &block).tap do |meta|
131
+ relate(name, meta)
132
+ reference(meta)
133
+ autosave(meta)
134
+ validates_relation(meta)
135
+ end
136
+ end
137
+ alias :belongs_to_related :belongs_to
138
+ alias :referenced_in :belongs_to
139
+
140
+ # Adds a relational association from a parent Document to many
141
+ # Documents in another database or collection.
142
+ #
143
+ # @example Define the relation.
144
+ #
145
+ # class Person
146
+ # include Mongoid::Document
147
+ # has_many :posts
148
+ # end
149
+ #
150
+ # class Game
151
+ # include Mongoid::Document
152
+ # belongs_to :person
153
+ # end
154
+ #
155
+ # @param [ Symbol ] name The name of the relation.
156
+ # @param [ Hash ] options The relation options.
157
+ # @param [ Proc ] block Optional block for defining extensions.
158
+ def has_many(name, options = {}, &block)
159
+ characterize(name, Referenced::Many, options, &block).tap do |meta|
160
+ relate(name, meta)
161
+ reference(meta)
162
+ autosave(meta)
163
+ validates_relation(meta)
164
+ end
165
+ end
166
+ alias :has_many_related :has_many
167
+ alias :references_many :has_many
168
+
169
+ # Adds a relational many-to-many association between many of this
170
+ # Document and many of another Document.
171
+ #
172
+ # @example Define the relation.
173
+ #
174
+ # class Person
175
+ # include Mongoid::Document
176
+ # has_and_belongs_to_many :preferences
177
+ # end
178
+ #
179
+ # class Preference
180
+ # include Mongoid::Document
181
+ # has_and_belongs_to_many :people
182
+ # end
183
+ #
184
+ # @param [ Symbol ] name The name of the relation.
185
+ # @param [ Hash ] options The relation options.
186
+ # @param [ Proc ] block Optional block for defining extensions.
187
+ #
188
+ # @since 2.0.0.rc.1
189
+ def has_and_belongs_to_many(name, options = {}, &block)
190
+ characterize(name, Referenced::ManyToMany, options, &block).tap do |meta|
191
+ relate(name, meta)
192
+ reference(meta, Array)
193
+ autosave(meta)
194
+ validates_relation(meta)
195
+ synced(meta)
196
+ end
197
+ end
198
+ alias :references_and_referenced_in_many :has_and_belongs_to_many
199
+
200
+ # Adds a relational association from the child Document to a Document in
201
+ # another database or collection.
202
+ #
203
+ # @example Define the relation.
204
+ #
205
+ # class Game
206
+ # include Mongoid::Document
207
+ # belongs_to :person
208
+ # end
209
+ #
210
+ # class Person
211
+ # include Mongoid::Document
212
+ # has_one :game
213
+ # end
214
+ #
215
+ # @param [ Symbol ] name The name of the relation.
216
+ # @param [ Hash ] options The relation options.
217
+ # @param [ Proc ] block Optional block for defining extensions.
218
+ def has_one(name, options = {}, &block)
219
+ characterize(name, Referenced::One, options, &block).tap do |meta|
220
+ relate(name, meta)
221
+ reference(meta)
222
+ builder(name, meta).creator(name).autosave(meta)
223
+ validates_relation(meta)
224
+ end
225
+ end
226
+ alias :has_one_related :has_one
227
+ alias :references_one :has_one
228
+
229
+ private
230
+
231
+ # Create the metadata for the relation.
232
+ #
233
+ # @example Create the metadata.
234
+ # Person.characterize(:posts, Referenced::Many, {})
235
+ #
236
+ # @param [ Symbol ] name The name of the relation.
237
+ # @param [ Object ] relation The type of relation.
238
+ # @param [ Hash ] options The relation options.
239
+ # @param [ Proc ] block Optional block for defining extensions.
240
+ #
241
+ # @return [ Metadata ] The metadata for the relation.
242
+ def characterize(name, relation, options, &block)
243
+ Metadata.new({
244
+ :relation => relation,
245
+ :extend => create_extension_module(name, &block),
246
+ :inverse_class_name => self.name,
247
+ :name => name
248
+ }.merge(options))
249
+ end
250
+
251
+ # Generate a named extension module suitable for marshaling
252
+ #
253
+ # @example Get the module.
254
+ # Person.create_extension_module(:posts, &block)
255
+ #
256
+ # @param [ Symbol ] name The name of the relation.
257
+ # @param [ Proc ] block Optional block for defining extensions.
258
+ #
259
+ # @return [ Module, nil ] The extension or nil.
260
+ #
261
+ # @since 2.1.0
262
+ def create_extension_module(name, &block)
263
+ if block
264
+ extension_module_name =
265
+ "#{self.to_s.demodulize}#{name.to_s.camelize}RelationExtension"
266
+ silence_warnings do
267
+ self.const_set(extension_module_name, Module.new(&block))
268
+ end
269
+ "#{self}::#{extension_module_name}".constantize
270
+ end
271
+ end
272
+
273
+ # Defines a field to be used as a foreign key in the relation and
274
+ # indexes it if defined.
275
+ #
276
+ # @example Set up the relational fields and indexes.
277
+ # Person.reference(metadata)
278
+ #
279
+ # @param [ Metadata ] metadata The metadata for the relation.
280
+ def reference(metadata, type = Object)
281
+ polymorph(metadata).cascade(metadata)
282
+ if metadata.relation.stores_foreign_key?
283
+ key = metadata.foreign_key
284
+ field(
285
+ key,
286
+ :type => type,
287
+ :identity => true,
288
+ :metadata => metadata,
289
+ :default => metadata.foreign_key_default
290
+ )
291
+ index(key, :background => true) if metadata.indexed?
292
+ end
293
+ end
294
+
295
+ # Creates a relation for the given name, metadata and relation. It adds
296
+ # the metadata to the relations hash and has the accessors set up.
297
+ #
298
+ # @example Set up the relation and accessors.
299
+ # Person.relate(:addresses, Metadata)
300
+ #
301
+ # @param [ Symbol ] name The name of the relation.
302
+ # @param [ Metadata ] metadata The metadata for the relation.
303
+ def relate(name, metadata)
304
+ self.relations = relations.merge(name.to_s => metadata)
305
+ getter(name, metadata).setter(name, metadata)
306
+ end
307
+ end
308
+ end
309
+ end
310
+ end