mongoid 2.0.2 → 2.1.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 (240) hide show
  1. data/README.rdoc +3 -1
  2. data/Rakefile +3 -2
  3. data/lib/config/locales/bg.yml +6 -0
  4. data/lib/config/locales/de.yml +6 -0
  5. data/lib/config/locales/en-GB.yml +48 -0
  6. data/lib/config/locales/en.yml +6 -3
  7. data/lib/config/locales/es.yml +6 -0
  8. data/lib/config/locales/fr.yml +6 -0
  9. data/lib/config/locales/hi.yml +39 -0
  10. data/lib/config/locales/hu.yml +13 -7
  11. data/lib/config/locales/id.yml +3 -0
  12. data/lib/config/locales/it.yml +7 -1
  13. data/lib/config/locales/ja.yml +4 -1
  14. data/lib/config/locales/kr.yml +9 -34
  15. data/lib/config/locales/nl.yml +6 -0
  16. data/lib/config/locales/pl.yml +6 -0
  17. data/lib/config/locales/pt-BR.yml +6 -0
  18. data/lib/config/locales/pt.yml +6 -0
  19. data/lib/config/locales/ro.yml +6 -0
  20. data/lib/config/locales/ru.yml +6 -0
  21. data/lib/config/locales/sv.yml +6 -0
  22. data/lib/config/locales/vi.yml +3 -0
  23. data/lib/config/locales/zh-CN.yml +6 -0
  24. data/lib/mongoid.rb +51 -45
  25. data/lib/mongoid/atomic.rb +145 -0
  26. data/lib/mongoid/atomic/modifiers.rb +109 -0
  27. data/lib/mongoid/atomic/paths.rb +3 -0
  28. data/lib/mongoid/atomic/paths/embedded.rb +43 -0
  29. data/lib/mongoid/atomic/paths/embedded/many.rb +44 -0
  30. data/lib/mongoid/atomic/paths/embedded/one.rb +43 -0
  31. data/lib/mongoid/atomic/paths/root.rb +40 -0
  32. data/lib/mongoid/attributes.rb +12 -23
  33. data/lib/mongoid/attributes/processing.rb +5 -5
  34. data/lib/mongoid/callbacks.rb +2 -0
  35. data/lib/mongoid/collection.rb +12 -59
  36. data/lib/mongoid/collections.rb +23 -20
  37. data/lib/mongoid/collections/master.rb +6 -4
  38. data/lib/mongoid/collections/operations.rb +1 -0
  39. data/lib/mongoid/collections/retry.rb +7 -0
  40. data/lib/mongoid/components.rb +2 -2
  41. data/lib/mongoid/config.rb +42 -55
  42. data/lib/mongoid/config/database.rb +6 -2
  43. data/lib/mongoid/config/replset_database.rb +7 -3
  44. data/lib/mongoid/contexts.rb +9 -3
  45. data/lib/mongoid/contexts/enumerable.rb +7 -3
  46. data/lib/mongoid/contexts/mongo.rb +139 -101
  47. data/lib/mongoid/criteria.rb +86 -69
  48. data/lib/mongoid/criterion/complex.rb +32 -5
  49. data/lib/mongoid/criterion/inclusion.rb +4 -2
  50. data/lib/mongoid/criterion/optional.rb +111 -86
  51. data/lib/mongoid/criterion/selector.rb +8 -4
  52. data/lib/mongoid/cursor.rb +27 -27
  53. data/lib/mongoid/dirty.rb +54 -214
  54. data/lib/mongoid/document.rb +37 -39
  55. data/lib/mongoid/errors/document_not_found.rb +3 -4
  56. data/lib/mongoid/errors/invalid_collection.rb +2 -3
  57. data/lib/mongoid/errors/invalid_database.rb +2 -3
  58. data/lib/mongoid/errors/invalid_field.rb +2 -3
  59. data/lib/mongoid/errors/invalid_options.rb +19 -7
  60. data/lib/mongoid/errors/invalid_type.rb +2 -3
  61. data/lib/mongoid/errors/mongoid_error.rb +5 -6
  62. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +2 -3
  63. data/lib/mongoid/errors/unsupported_version.rb +2 -3
  64. data/lib/mongoid/errors/validations.rb +2 -3
  65. data/lib/mongoid/extensions.rb +8 -62
  66. data/lib/mongoid/extensions/array/deletion.rb +29 -0
  67. data/lib/mongoid/extensions/false_class/equality.rb +14 -1
  68. data/lib/mongoid/extensions/hash/criteria_helpers.rb +21 -10
  69. data/lib/mongoid/extensions/hash/scoping.rb +14 -1
  70. data/lib/mongoid/extensions/nil/collectionization.rb +12 -1
  71. data/lib/mongoid/extensions/object/reflections.rb +33 -2
  72. data/lib/mongoid/extensions/object_id/conversions.rb +2 -36
  73. data/lib/mongoid/extensions/proc/scoping.rb +14 -1
  74. data/lib/mongoid/extensions/string/conversions.rb +4 -16
  75. data/lib/mongoid/extensions/string/inflections.rb +35 -14
  76. data/lib/mongoid/extensions/symbol/inflections.rb +38 -12
  77. data/lib/mongoid/extensions/true_class/equality.rb +14 -1
  78. data/lib/mongoid/extras.rb +11 -30
  79. data/lib/mongoid/factory.rb +1 -1
  80. data/lib/mongoid/fields.rb +121 -29
  81. data/lib/mongoid/fields/mappings.rb +36 -0
  82. data/lib/mongoid/fields/serializable.rb +131 -0
  83. data/lib/mongoid/fields/serializable/array.rb +64 -0
  84. data/lib/mongoid/fields/serializable/big_decimal.rb +42 -0
  85. data/lib/mongoid/fields/serializable/bignum.rb +10 -0
  86. data/lib/mongoid/fields/serializable/binary.rb +11 -0
  87. data/lib/mongoid/fields/serializable/boolean.rb +44 -0
  88. data/lib/mongoid/fields/serializable/date.rb +51 -0
  89. data/lib/mongoid/fields/serializable/date_time.rb +28 -0
  90. data/lib/mongoid/fields/serializable/fixnum.rb +10 -0
  91. data/lib/mongoid/fields/serializable/float.rb +33 -0
  92. data/lib/mongoid/fields/serializable/foreign_keys/array.rb +56 -0
  93. data/lib/mongoid/fields/serializable/foreign_keys/object.rb +43 -0
  94. data/lib/mongoid/fields/serializable/hash.rb +25 -0
  95. data/lib/mongoid/fields/serializable/integer.rb +33 -0
  96. data/lib/mongoid/fields/serializable/object.rb +11 -0
  97. data/lib/mongoid/fields/serializable/object_id.rb +32 -0
  98. data/lib/mongoid/fields/serializable/range.rb +42 -0
  99. data/lib/mongoid/fields/serializable/set.rb +42 -0
  100. data/lib/mongoid/fields/serializable/string.rb +28 -0
  101. data/lib/mongoid/fields/serializable/symbol.rb +28 -0
  102. data/lib/mongoid/fields/serializable/time.rb +12 -0
  103. data/lib/mongoid/fields/serializable/time_with_zone.rb +12 -0
  104. data/lib/mongoid/fields/serializable/timekeeping.rb +102 -0
  105. data/lib/mongoid/finders.rb +61 -37
  106. data/lib/mongoid/hierarchy.rb +43 -8
  107. data/lib/mongoid/identity_map.rb +106 -0
  108. data/lib/mongoid/indexes.rb +17 -1
  109. data/lib/mongoid/javascript.rb +2 -3
  110. data/lib/mongoid/keys.rb +10 -21
  111. data/lib/mongoid/logger.rb +22 -1
  112. data/lib/mongoid/matchers/all.rb +10 -0
  113. data/lib/mongoid/matchers/default.rb +1 -1
  114. data/lib/mongoid/matchers/exists.rb +10 -0
  115. data/lib/mongoid/matchers/gt.rb +10 -0
  116. data/lib/mongoid/matchers/gte.rb +10 -0
  117. data/lib/mongoid/matchers/in.rb +10 -0
  118. data/lib/mongoid/matchers/lt.rb +10 -0
  119. data/lib/mongoid/matchers/lte.rb +10 -0
  120. data/lib/mongoid/matchers/ne.rb +10 -0
  121. data/lib/mongoid/matchers/nin.rb +10 -0
  122. data/lib/mongoid/matchers/or.rb +7 -4
  123. data/lib/mongoid/matchers/size.rb +10 -0
  124. data/lib/mongoid/multi_database.rb +26 -6
  125. data/lib/mongoid/multi_parameter_attributes.rb +40 -17
  126. data/lib/mongoid/named_scope.rb +1 -2
  127. data/lib/mongoid/nested_attributes.rb +4 -1
  128. data/lib/mongoid/observer.rb +108 -5
  129. data/lib/mongoid/paranoia.rb +26 -26
  130. data/lib/mongoid/persistence.rb +15 -21
  131. data/lib/mongoid/persistence/atomic.rb +135 -0
  132. data/lib/mongoid/persistence/atomic/add_to_set.rb +11 -8
  133. data/lib/mongoid/persistence/atomic/bit.rb +37 -0
  134. data/lib/mongoid/persistence/atomic/inc.rb +9 -6
  135. data/lib/mongoid/persistence/atomic/operation.rb +48 -7
  136. data/lib/mongoid/persistence/atomic/pop.rb +34 -0
  137. data/lib/mongoid/persistence/atomic/pull.rb +34 -0
  138. data/lib/mongoid/persistence/atomic/pull_all.rb +10 -9
  139. data/lib/mongoid/persistence/atomic/push.rb +8 -5
  140. data/lib/mongoid/persistence/atomic/push_all.rb +31 -0
  141. data/lib/mongoid/persistence/atomic/rename.rb +31 -0
  142. data/lib/mongoid/persistence/atomic/set.rb +30 -0
  143. data/lib/mongoid/persistence/atomic/unset.rb +28 -0
  144. data/lib/mongoid/persistence/deletion.rb +32 -0
  145. data/lib/mongoid/persistence/insertion.rb +41 -0
  146. data/lib/mongoid/persistence/modification.rb +37 -0
  147. data/lib/mongoid/persistence/operations.rb +214 -0
  148. data/lib/mongoid/persistence/operations/embedded/insert.rb +42 -0
  149. data/lib/mongoid/persistence/operations/embedded/remove.rb +40 -0
  150. data/lib/mongoid/persistence/operations/insert.rb +34 -0
  151. data/lib/mongoid/persistence/operations/remove.rb +33 -0
  152. data/lib/mongoid/persistence/operations/update.rb +53 -0
  153. data/lib/mongoid/railtie.rb +21 -33
  154. data/lib/mongoid/railties/database.rake +12 -12
  155. data/lib/mongoid/relations.rb +9 -5
  156. data/lib/mongoid/relations/accessors.rb +15 -36
  157. data/lib/mongoid/relations/auto_save.rb +2 -2
  158. data/lib/mongoid/relations/binding.rb +28 -1
  159. data/lib/mongoid/relations/bindings/embedded/in.rb +17 -30
  160. data/lib/mongoid/relations/bindings/embedded/many.rb +16 -21
  161. data/lib/mongoid/relations/bindings/embedded/one.rb +11 -16
  162. data/lib/mongoid/relations/bindings/referenced/in.rb +31 -32
  163. data/lib/mongoid/relations/bindings/referenced/many.rb +19 -61
  164. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +15 -63
  165. data/lib/mongoid/relations/bindings/referenced/one.rb +18 -26
  166. data/lib/mongoid/relations/builder.rb +4 -2
  167. data/lib/mongoid/relations/builders.rb +21 -2
  168. data/lib/mongoid/relations/builders/embedded/in.rb +5 -1
  169. data/lib/mongoid/relations/builders/embedded/many.rb +12 -4
  170. data/lib/mongoid/relations/builders/embedded/one.rb +5 -1
  171. data/lib/mongoid/relations/builders/nested_attributes/many.rb +2 -2
  172. data/lib/mongoid/relations/builders/nested_attributes/one.rb +1 -1
  173. data/lib/mongoid/relations/builders/referenced/in.rb +2 -5
  174. data/lib/mongoid/relations/builders/referenced/many.rb +2 -3
  175. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +14 -5
  176. data/lib/mongoid/relations/builders/referenced/one.rb +2 -3
  177. data/lib/mongoid/relations/embedded/atomic.rb +2 -2
  178. data/lib/mongoid/relations/embedded/in.rb +72 -41
  179. data/lib/mongoid/relations/embedded/many.rb +116 -120
  180. data/lib/mongoid/relations/embedded/one.rb +59 -41
  181. data/lib/mongoid/relations/embedded/sort.rb +31 -0
  182. data/lib/mongoid/relations/macros.rb +28 -24
  183. data/lib/mongoid/relations/many.rb +10 -103
  184. data/lib/mongoid/relations/metadata.rb +335 -38
  185. data/lib/mongoid/relations/one.rb +7 -32
  186. data/lib/mongoid/relations/options.rb +47 -0
  187. data/lib/mongoid/relations/proxy.rb +29 -28
  188. data/lib/mongoid/relations/referenced/batch.rb +2 -3
  189. data/lib/mongoid/relations/referenced/in.rb +66 -53
  190. data/lib/mongoid/relations/referenced/many.rb +216 -143
  191. data/lib/mongoid/relations/referenced/many_to_many.rb +132 -163
  192. data/lib/mongoid/relations/referenced/one.rb +76 -58
  193. data/lib/mongoid/relations/synchronization.rb +113 -0
  194. data/lib/mongoid/relations/targets.rb +2 -0
  195. data/lib/mongoid/relations/targets/enumerable.rb +329 -0
  196. data/lib/mongoid/safety.rb +24 -156
  197. data/lib/mongoid/serialization.rb +21 -0
  198. data/lib/mongoid/state.rb +34 -0
  199. data/lib/mongoid/threaded.rb +175 -0
  200. data/lib/mongoid/timestamps/updated.rb +1 -1
  201. data/lib/mongoid/validations.rb +3 -7
  202. data/lib/mongoid/version.rb +1 -1
  203. data/lib/mongoid/versioning.rb +61 -7
  204. data/lib/rack/mongoid.rb +2 -0
  205. data/lib/rack/mongoid/middleware/identity_map.rb +38 -0
  206. data/lib/rails/generators/mongoid/model/model_generator.rb +1 -1
  207. data/lib/rails/generators/mongoid/model/templates/{model.rb → model.rb.tt} +0 -0
  208. data/lib/rails/generators/mongoid/observer/observer_generator.rb +1 -1
  209. data/lib/rails/generators/mongoid/observer/templates/{observer.rb → observer.rb.tt} +0 -0
  210. data/lib/rails/mongoid.rb +17 -17
  211. metadata +136 -102
  212. data/lib/mongoid/atomicity.rb +0 -111
  213. data/lib/mongoid/collections/cyclic_iterator.rb +0 -34
  214. data/lib/mongoid/collections/slaves.rb +0 -61
  215. data/lib/mongoid/extensions/array/conversions.rb +0 -23
  216. data/lib/mongoid/extensions/array/parentization.rb +0 -13
  217. data/lib/mongoid/extensions/big_decimal/conversions.rb +0 -19
  218. data/lib/mongoid/extensions/binary/conversions.rb +0 -17
  219. data/lib/mongoid/extensions/boolean/conversions.rb +0 -27
  220. data/lib/mongoid/extensions/date/conversions.rb +0 -25
  221. data/lib/mongoid/extensions/datetime/conversions.rb +0 -12
  222. data/lib/mongoid/extensions/float/conversions.rb +0 -20
  223. data/lib/mongoid/extensions/hash/conversions.rb +0 -19
  224. data/lib/mongoid/extensions/integer/conversions.rb +0 -20
  225. data/lib/mongoid/extensions/object/conversions.rb +0 -25
  226. data/lib/mongoid/extensions/range/conversions.rb +0 -25
  227. data/lib/mongoid/extensions/set/conversions.rb +0 -20
  228. data/lib/mongoid/extensions/symbol/conversions.rb +0 -21
  229. data/lib/mongoid/extensions/time_conversions.rb +0 -38
  230. data/lib/mongoid/field.rb +0 -162
  231. data/lib/mongoid/paths.rb +0 -61
  232. data/lib/mongoid/persistence/command.rb +0 -71
  233. data/lib/mongoid/persistence/insert.rb +0 -53
  234. data/lib/mongoid/persistence/insert_embedded.rb +0 -43
  235. data/lib/mongoid/persistence/remove.rb +0 -44
  236. data/lib/mongoid/persistence/remove_all.rb +0 -40
  237. data/lib/mongoid/persistence/remove_embedded.rb +0 -48
  238. data/lib/mongoid/persistence/update.rb +0 -77
  239. data/lib/mongoid/safe.rb +0 -23
  240. data/lib/mongoid/validations/referenced.rb +0 -58
@@ -7,21 +7,20 @@ module Mongoid #:nodoc:
7
7
 
8
8
  # Delegate to the criteria methods that are natural for creating a new
9
9
  # criteria.
10
- [ :all_in, :any_in, :any_of, :asc, :ascending, :avg, :desc, :descending,
11
- :excludes, :limit, :max, :min, :not_in, :only, :order_by,
12
- :skip, :sum, :without, :where, :update, :update_all, :near ].each do |name|
13
- define_method(name) do |*args|
14
- criteria.send(name, *args)
15
- end
16
- end
10
+ critera_methods = [ :all_in, :any_in, :any_of, :asc, :ascending, :avg,
11
+ :desc, :descending, :excludes, :limit, :max, :min,
12
+ :not_in, :only, :order_by, :skip, :sum, :without,
13
+ :where, :update, :update_all, :near ]
14
+ delegate *(critera_methods.dup << {:to => :criteria})
17
15
 
18
- # Find +Documents+ given the conditions.
16
+ # Find all documents that match the given conditions.
19
17
  #
20
- # Options:
18
+ # @example Find all matching documents given conditions.
19
+ # Person.all(:conditions => { :attribute => "value" })
21
20
  #
22
- # args: A +Hash+ with a conditions key and other options
21
+ # @param [ Array ] args The conditions with options.
23
22
  #
24
- # <tt>Person.all(:conditions => { :attribute => "value" })</tt>
23
+ # @return [ Criteria ] The matching documents.
25
24
  def all(*args)
26
25
  find(:all, *args)
27
26
  end
@@ -29,12 +28,22 @@ module Mongoid #:nodoc:
29
28
  # Returns a count of matching records in the database based on the
30
29
  # provided arguments.
31
30
  #
32
- # <tt>Person.count(:conditions => { :attribute => "value" })</tt>
31
+ # @example Get the count of matching documents.
32
+ # Person.count(:conditions => { :attribute => "value" })
33
+ #
34
+ # @param [ Array ] args The conditions.
35
+ #
36
+ # @return [ Integer ] The number of matching documents.
33
37
  def count(*args)
34
38
  find(:all, *args).count
35
39
  end
36
40
 
37
41
  # Returns true if count is zero
42
+ #
43
+ # @example Are there no saved documents for this model?
44
+ # Person.empty?
45
+ #
46
+ # @return [ true, false ] If the collection is empty.
38
47
  def empty?
39
48
  count == 0
40
49
  end
@@ -42,7 +51,10 @@ module Mongoid #:nodoc:
42
51
  # Returns true if there are on document in database based on the
43
52
  # provided arguments.
44
53
  #
45
- # <tt>Person.exists?(:conditions => { :attribute => "value" })</tt>
54
+ # @example Do any documents exist for the conditions?
55
+ # Person.exists?(:conditions => { :attribute => "value" })
56
+ #
57
+ # @param [ Array ] args The conditions.
46
58
  def exists?(*args)
47
59
  find(:all, *args).limit(1).count == 1
48
60
  end
@@ -55,71 +67,83 @@ module Mongoid #:nodoc:
55
67
  # it will attempt to find either a single +Document+ or multiples based
56
68
  # on the conditions provided and the first parameter.
57
69
  #
58
- # Example:
70
+ # @example Find the first matching document.
71
+ # Person.find(:first, :conditions => { :attribute => "value" })
59
72
  #
60
- # <tt>Person.find(:first, :conditions => { :attribute => "value" })</tt>
61
- # <tt>Person.find(:all, :conditions => { :attribute => "value" })</tt>
62
- # <tt>Person.find(BSON::ObjectId)</tt>
73
+ # @example Find all matching documents.
74
+ # Person.find(:all, :conditions => { :attribute => "value" })
63
75
  #
64
- # Options:
76
+ # @example Find a single document by an id.
77
+ # Person.find(BSON::ObjectId)
65
78
  #
66
- # args: An assortment of finder options.
79
+ # @param [ Array ] args An assortment of finder options.
67
80
  #
68
- # Returns:
69
- #
70
- # A document or criteria.
81
+ # @return [ Document, nil, Criteria ] A document or matching documents.
71
82
  def find(*args)
72
83
  criteria.find(*args)
73
84
  end
74
85
 
75
86
  # Find the first +Document+ given the conditions, or creates a new document
76
- # with the conditions that were supplied
87
+ # with the conditions that were supplied.
77
88
  #
78
- # Options:
89
+ # @example Find or create the document.
90
+ # Person.find_or_create_by(:attribute => "value")
79
91
  #
80
- # args: A +Hash+ of attributes
92
+ # @param [ Hash ] attrs The attributes to check.
81
93
  #
82
- # <tt>Person.find_or_create_by(:attribute => "value")</tt>
94
+ # @return [ Document ] A matching or newly created document.
83
95
  def find_or_create_by(attrs = {}, &block)
84
96
  find_or(:create, attrs, &block)
85
97
  end
86
98
 
87
- # Find the first +Document+ given the conditions, or instantiates a new document
88
- # with the conditions that were supplied
99
+ # Find the first +Document+ given the conditions, or initializes a new document
100
+ # with the conditions that were supplied.
89
101
  #
90
- # Options:
102
+ # @example Find or initialize the document.
103
+ # Person.find_or_initialize_by(:attribute => "value")
91
104
  #
92
- # args: A +Hash+ of attributes
105
+ # @param [ Hash ] attrs The attributes to check.
93
106
  #
94
- # <tt>Person.find_or_initialize_by(:attribute => "value")</tt>
107
+ # @return [ Document ] A matching or newly initialized document.
95
108
  def find_or_initialize_by(attrs = {}, &block)
96
109
  find_or(:new, attrs, &block)
97
110
  end
98
111
 
99
112
  # Find the first +Document+ given the conditions.
100
113
  #
101
- # Options:
114
+ # @example Find the first document.
115
+ # Person.first(:conditions => { :attribute => "value" })
102
116
  #
103
- # args: A +Hash+ with a conditions key and other options
117
+ # @param [ Array ] args The conditions with options.
104
118
  #
105
- # <tt>Person.first(:conditions => { :attribute => "value" })</tt>
119
+ # @return [ Document ] The first matching document.
106
120
  def first(*args)
107
121
  find(:first, *args)
108
122
  end
109
123
 
110
124
  # Find the last +Document+ given the conditions.
111
125
  #
112
- # Options:
126
+ # @example Find the last document.
127
+ # Person.last(:conditions => { :attribute => "value" })
113
128
  #
114
- # args: A +Hash+ with a conditions key and other options
129
+ # @param [ Array ] args The conditions with options.
115
130
  #
116
- # <tt>Person.last(:conditions => { :attribute => "value" })</tt>
131
+ # @return [ Document ] The last matching document.
117
132
  def last(*args)
118
133
  find(:last, *args)
119
134
  end
120
135
 
121
136
  protected
137
+
122
138
  # Find the first object or create/initialize it.
139
+ #
140
+ # @example Find or perform an action.
141
+ # Person.find_or(:create, :name => "Dev")
142
+ #
143
+ # @param [ Symbol ] method The method to invoke.
144
+ # @param [ Hash ] attrs The attributes to query or set.
145
+ #
146
+ # @return [ Document ] The first or new document.
123
147
  def find_or(method, attrs = {}, &block)
124
148
  first(:conditions => attrs) || send(method, attrs, &block)
125
149
  end
@@ -2,6 +2,7 @@
2
2
  module Mongoid #:nodoc
3
3
  module Hierarchy #:nodoc
4
4
  extend ActiveSupport::Concern
5
+
5
6
  included do
6
7
  attr_accessor :_parent
7
8
  end
@@ -33,16 +34,18 @@ module Mongoid #:nodoc
33
34
  #
34
35
  # @return [ Array<Document> ] All child documents in the hierarchy.
35
36
  def _children
36
- relations.inject([]) do |children, (name, metadata)|
37
- children.tap do |kids|
38
- if metadata.embedded? && name != "versions"
39
- child = send(name)
40
- child.to_a.each do |doc|
41
- kids.push(doc).concat(doc._children)
42
- end unless child.blank?
37
+ @_children ||=
38
+ [].tap do |children|
39
+ relations.each_pair do |name, metadata|
40
+ if metadata.embedded?
41
+ child = send(name)
42
+ child.to_a.each do |doc|
43
+ children.push(doc)
44
+ children.concat(doc._children) unless metadata.versioned?
45
+ end if child
46
+ end
43
47
  end
44
48
  end
45
- end
46
49
  end
47
50
 
48
51
  # Determines if the document is a subclass of another document.
@@ -68,6 +71,38 @@ module Mongoid #:nodoc
68
71
  self._parent = document
69
72
  end
70
73
 
74
+ # Remove a child document from this parent. If an embeds one then set to
75
+ # nil, otherwise remove from the embeds many.
76
+ #
77
+ # This is called from the +RemoveEmbedded+ persistence command.
78
+ #
79
+ # @example Remove the child.
80
+ # document.remove_child(child)
81
+ #
82
+ # @param [ Document ] child The child (embedded) document to remove.
83
+ #
84
+ # @since 2.0.0.beta.1
85
+ def remove_child(child)
86
+ name = child.metadata.name
87
+ child.embedded_one? ? remove_ivar(name) : send(name).delete(child)
88
+ end
89
+
90
+ # After children are persisted we can call this to move all their changes
91
+ # and flag them as persisted in one call.
92
+ #
93
+ # @example Reset the children.
94
+ # document.reset_persisted_children
95
+ #
96
+ # @return [ Array<Document> ] The children.
97
+ #
98
+ # @since 2.1.0
99
+ def reset_persisted_children
100
+ _children.each do |child|
101
+ child.move_changes
102
+ child.new_record = false
103
+ end
104
+ end
105
+
71
106
  # Return the root document in the object graph. If the current document
72
107
  # is the root object in the graph it will return self.
73
108
  #
@@ -0,0 +1,106 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+
4
+ # Defines behaviour for the identity map in Mongoid.
5
+ class IdentityMap < Hash
6
+
7
+ # Get a document from the identity map by its id.
8
+ #
9
+ # @example Get the document from the map.
10
+ # map.get(Person, id)
11
+ #
12
+ # @param [ Class ] klass The class of the document.
13
+ # @param [ Object ] id The document id.
14
+ #
15
+ # @return [ Document ] The matching document.
16
+ #
17
+ # @since 2.1.0
18
+ def get(klass, id)
19
+ return nil unless Mongoid.identity_map_enabled?
20
+ documents_for(klass)[id]
21
+ end
22
+
23
+ # Get a single document that matches the provided criteria.
24
+ #
25
+ # @example Get the document for the criteria.
26
+ # map.match(Person.where(:_id => id))
27
+ #
28
+ # @param [ Criteria ] criteria The criteria to match.
29
+ #
30
+ # @return [ Document ] The first matching document.
31
+ #
32
+ # @since 2.1.0
33
+ def match(criteria)
34
+ return nil unless Mongoid.identity_map_enabled?
35
+ documents_for(criteria.klass).values.detect do |doc|
36
+ doc.matches?(criteria.selector)
37
+ end
38
+ end
39
+
40
+ # Remove the document from the identity map.
41
+ #
42
+ # @example Remove the document.
43
+ # map.removed(person)
44
+ #
45
+ # @param [ Document ] document The document to remove.
46
+ #
47
+ # @return [ Document, nil ] The removed document.
48
+ #
49
+ # @since 2.1.0
50
+ def remove(document)
51
+ return nil unless Mongoid.identity_map_enabled? && document && document.id
52
+ documents_for(document.class).delete(document.id)
53
+ end
54
+
55
+ # Puts a document in the identity map, accessed by it's id.
56
+ #
57
+ # @example Put the document in the map.
58
+ # identity_map.set(document)
59
+ #
60
+ # @param [ Document ] document The document to place in the map.
61
+ #
62
+ # @return [ Document ] The provided document.
63
+ #
64
+ # @since 2.1.0
65
+ def set(document)
66
+ return nil unless Mongoid.identity_map_enabled? && document && document.id
67
+ documents_for(document.class)[document.id] = document
68
+ end
69
+
70
+ private
71
+
72
+ # Get the documents in the identity map for a specific class.
73
+ #
74
+ # @example Get the documents for the class.
75
+ # map.documents_for(Person)
76
+ #
77
+ # @param [ Class ] klass The class to retrieve.
78
+ #
79
+ # @return [ Hash ] The documents.
80
+ #
81
+ # @since 2.1.0
82
+ def documents_for(klass)
83
+ self[klass] ||= {}
84
+ end
85
+
86
+ class << self
87
+
88
+ # For ease of access we provide the same API to the identity map on the
89
+ # class level, which in turn just gets the identity map that is on the
90
+ # current thread.
91
+ #
92
+ # @example Get a document from the current identity map by id.
93
+ # IdentityMap.get(id)
94
+ #
95
+ # @example Set a document in the current identity map.
96
+ # IdentityMap.set(document)
97
+ #
98
+ # @since 2.1.0
99
+ delegate *(
100
+ Hash.public_instance_methods(false) +
101
+ IdentityMap.public_instance_methods(false) <<
102
+ { :to => :"Mongoid::Threaded.identity_map" }
103
+ )
104
+ end
105
+ end
106
+ end
@@ -2,6 +2,7 @@
2
2
  module Mongoid #:nodoc
3
3
  module Indexes #:nodoc
4
4
  extend ActiveSupport::Concern
5
+
5
6
  included do
6
7
  cattr_accessor :index_options
7
8
  self.index_options = {}
@@ -10,16 +11,22 @@ module Mongoid #:nodoc
10
11
  module ClassMethods #:nodoc
11
12
 
12
13
  # Send the actual index creation comments to the MongoDB driver
14
+ #
15
+ # @example Create the indexes for the class.
16
+ # Person.create_indexes
13
17
  def create_indexes
14
18
  return unless index_options
15
19
  current_collection = self._collection || set_collection
16
- index_options.each do |name, options|
20
+ index_options.each_pair do |name, options|
17
21
  current_collection.create_index(name, options)
18
22
  end
19
23
  end
20
24
 
21
25
  # Add the default indexes to the root document if they do not already
22
26
  # exist. Currently this is only _type.
27
+ #
28
+ # @example Add Mongoid internal indexes.
29
+ # Person.add_indexes
23
30
  def add_indexes
24
31
  if hereditary? && !index_options[:_type]
25
32
  self.index_options[:_type] = {:unique => false, :background => true}
@@ -29,6 +36,15 @@ module Mongoid #:nodoc
29
36
 
30
37
  # Adds an index on the field specified. Options can be :unique => true or
31
38
  # :unique => false. It will default to the latter.
39
+ #
40
+ # @example Create a basic index.
41
+ # class Person
42
+ # include Mongoid::Document
43
+ # field :name, :type => String
44
+ # index :name, :background => true
45
+ #
46
+ # @param [ Symbol ] name The name of the field.
47
+ # @param [ Hash ] options The index options.
32
48
  def index(name, options = { :unique => false })
33
49
  self.index_options[name] = options
34
50
  create_indexes if Mongoid.autocreate_indexes
@@ -7,9 +7,8 @@ module Mongoid #:nodoc:
7
7
  # Load the javascript functions and define a class method for each one,
8
8
  # that memoizes the value.
9
9
  #
10
- # Example:
11
- #
12
- # <tt>Mongoid::Javascript.aggregate</tt>
10
+ # @example Get the function.
11
+ # Mongoid::Javascript.aggregate
13
12
  YAML.load(File.read(FUNCTIONS)).each_pair do |key, function|
14
13
  (class << self; self; end).class_eval <<-EOT
15
14
  def #{key}
@@ -7,8 +7,11 @@ module Mongoid #:nodoc:
7
7
  extend ActiveSupport::Concern
8
8
 
9
9
  included do
10
- cattr_accessor :primary_key, :object_ids
10
+ cattr_accessor :primary_key, :using_object_ids
11
+ self.using_object_ids = true
11
12
  delegate :primary_key, :using_object_ids?, :to => "self.class"
13
+
14
+ attr_reader :identifier
12
15
  end
13
16
 
14
17
  private
@@ -51,10 +54,9 @@ module Mongoid #:nodoc:
51
54
  #
52
55
  # @since 2.0.0
53
56
  def swap_composite_keys(&block)
54
- old_id, new_id = id.dup, identify
55
- @attributes["_id"] = old_id
57
+ @identifier, new_id = id.dup, identify
56
58
  block.call
57
- @attributes["_id"] = new_id
59
+ @identifier = nil
58
60
  end
59
61
 
60
62
  module ClassMethods #:nodoc:
@@ -76,8 +78,9 @@ module Mongoid #:nodoc:
76
78
  #
77
79
  # @since 2.0.0.beta.1
78
80
  def identity(options = {})
79
- fields["_id"].type = options[:type]
80
- @object_ids = id_is_object
81
+ type = options[:type]
82
+ replace_field("_id", type)
83
+ self.using_object_ids = (type == BSON::ObjectId)
81
84
  end
82
85
 
83
86
  # Defines the field that will be used for the id of this +Document+. This
@@ -110,21 +113,7 @@ module Mongoid #:nodoc:
110
113
  #
111
114
  # @since 1.0.0
112
115
  def using_object_ids?
113
- @object_ids ||= id_is_object
114
- end
115
-
116
- private
117
-
118
- # Is the id field type an object id?
119
- #
120
- # @example Is type an object id.
121
- # Class.id_is_object
122
- #
123
- # @return [ true, false ] Is the id an object id.
124
- #
125
- # @since 2.0.0
126
- def id_is_object
127
- fields["_id"].type == BSON::ObjectId
116
+ using_object_ids
128
117
  end
129
118
  end
130
119
  end