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,38 +7,6 @@ module Mongoid #:nodoc:
7
7
  # and Hashes.
8
8
  module Conversions
9
9
 
10
- # Set the BSON::ObjectId value.
11
- #
12
- # @example Set the value.
13
- # BSON::ObjectId.set("4c52c439931a90ab29000003")
14
- #
15
- # @param [ String, BSON::ObjectId ] value The value to set.
16
- #
17
- # @return [ BSON::ObjectId ] The set value.
18
- #
19
- # @since 1.0
20
- def set(value)
21
- if value.is_a?(::String)
22
- BSON::ObjectId.from_string(value) unless value.blank?
23
- else
24
- value
25
- end
26
- end
27
-
28
- # Get the BSON::ObjectId value.
29
- #
30
- # @example Get the value.
31
- # BSON::ObjectId.set(BSON::ObjectId.new)
32
- #
33
- # @param [ BSON::ObjectId ] value The value to get.
34
- #
35
- # @return [ BSON::ObjectId ] The value.
36
- #
37
- # @since 1.0
38
- def get(value)
39
- value
40
- end
41
-
42
10
  # Convert the supplied arguments to object ids based on the class
43
11
  # settings.
44
12
  #
@@ -73,10 +41,8 @@ module Mongoid #:nodoc:
73
41
  BSON::ObjectId.from_string(args)
74
42
  end
75
43
  when ::Array
76
- args = args.reject(&:blank?) if reject_blank
77
- args.map do |arg|
78
- convert(klass, arg, reject_blank)
79
- end
44
+ args.delete_if { |arg| arg.blank? } if reject_blank
45
+ args.replace(args.map { |arg| convert(klass, arg, reject_blank) })
80
46
  when ::Hash
81
47
  args.tap do |hash|
82
48
  hash.each_pair do |key, value|
@@ -2,7 +2,20 @@
2
2
  module Mongoid #:nodoc:
3
3
  module Extensions #:nodoc:
4
4
  module Proc #:nodoc:
5
- module Scoping #:nodoc:
5
+
6
+ # Adds functionality for criteria scoping/merging.
7
+ module Scoping
8
+
9
+ # Get the proc scoped for criteria merges.
10
+ #
11
+ # @example Get the hash.
12
+ # proc.scoped
13
+ #
14
+ # @param [ Array ] args The arguments to delegate to the proc.
15
+ #
16
+ # @return [ Object ] The result of the proc call.
17
+ #
18
+ # @since 1.0.0
6
19
  def scoped(*args)
7
20
  call(*args).scoped
8
21
  end
@@ -7,27 +7,15 @@ module Mongoid #:nodoc:
7
7
 
8
8
  # Convert the string to an array with the string in it.
9
9
  #
10
- # Example:
10
+ # @example Convert the string to an array.
11
+ # "Testing".to_a
11
12
  #
12
- # <tt>"Testing".to_a</tt>
13
+ # @return [ Array ] An array with only the string in it.
13
14
  #
14
- # Returns:
15
- #
16
- # An array with only the string in it.
15
+ # @since 1.0.0
17
16
  def to_a
18
17
  [ self ]
19
18
  end
20
-
21
- module ClassMethods #:nodoc:
22
-
23
- def get(value)
24
- value
25
- end
26
-
27
- def set(value)
28
- value.to_s unless value.nil?
29
- end
30
- end
31
19
  end
32
20
  end
33
21
  end
@@ -2,7 +2,10 @@
2
2
  module Mongoid #:nodoc:
3
3
  module Extensions #:nodoc:
4
4
  module String #:nodoc:
5
- module Inflections #:nodoc:
5
+
6
+ # This module contains convenience methods for string inflection and
7
+ # conversion.
8
+ module Inflections
6
9
 
7
10
  ActiveSupport::Inflector.inflections do |inflect|
8
11
  inflect.singular("address", "address")
@@ -26,7 +29,7 @@ module Mongoid #:nodoc:
26
29
  "*" => "-astx-",
27
30
  "+" => "-plus-",
28
31
  "," => "-comma-",
29
- "-" => "-dash-",
32
+ "-" => "-",
30
33
  "." => "-period-",
31
34
  "/" => "-fwdslsh-",
32
35
  ":" => "-colon-",
@@ -55,10 +58,22 @@ module Mongoid #:nodoc:
55
58
  "descending" => "ascending"
56
59
  }
57
60
 
61
+ # Convert the string to a collection friendly name.
62
+ #
63
+ # @example Collectionize the string.
64
+ # "namespace/model".collectionize
65
+ #
66
+ # @return [ String ] The string in collection friendly form.
58
67
  def collectionize
59
68
  tableize.gsub("/", "_")
60
69
  end
61
70
 
71
+ # Convert this string to a key friendly string.
72
+ #
73
+ # @example Convert to key.
74
+ # "testing".identify
75
+ #
76
+ # @return [ String ] The key friendly string.
62
77
  def identify
63
78
  if Mongoid.parameterize_keys
64
79
  key = ""
@@ -68,26 +83,32 @@ module Mongoid #:nodoc:
68
83
  end
69
84
  end
70
85
 
71
- def labelize
72
- underscore.humanize
73
- end
74
-
86
+ # Get the inverted sorting option.
87
+ #
88
+ # @example Get the inverted option.
89
+ # "asc".invert
90
+ #
91
+ # @return [ String ] The string inverted.
75
92
  def invert
76
93
  REVERSALS[self]
77
94
  end
78
95
 
79
- def singular?
80
- singularize == self
81
- end
82
-
83
- def plural?
84
- pluralize == self
85
- end
86
-
96
+ # Get the string as a getter string.
97
+ #
98
+ # @example Get the reader/getter
99
+ # "model=".reader
100
+ #
101
+ # @return [ String ] The string stripped of "=".
87
102
  def reader
88
103
  writer? ? gsub("=", "") : self
89
104
  end
90
105
 
106
+ # Is this string a writer?
107
+ #
108
+ # @example Is the string a setter method?
109
+ # "model=".writer?
110
+ #
111
+ # @return [ true, false ] If the string contains "=".
91
112
  def writer?
92
113
  include?("=")
93
114
  end
@@ -2,7 +2,10 @@
2
2
  module Mongoid #:nodoc:
3
3
  module Extensions #:nodoc:
4
4
  module Symbol #:nodoc:
5
- module Inflections #:nodoc:
5
+
6
+ # This module contains convenience methods for symbol inflection and
7
+ # conversion.
8
+ module Inflections
6
9
 
7
10
  REVERSALS = {
8
11
  :asc => :desc,
@@ -11,21 +14,44 @@ module Mongoid #:nodoc:
11
14
  :descending => :ascending
12
15
  }
13
16
 
17
+ # Get the inverted sorting option.
18
+ #
19
+ # @example Get the inverted option.
20
+ # :asc.invert
21
+ #
22
+ # @return [ String ] The string inverted.
14
23
  def invert
15
24
  REVERSALS[self]
16
25
  end
17
26
 
18
- def singular?
19
- to_s.singular?
20
- end
21
-
22
- def plural?
23
- to_s.plural?
24
- end
25
-
26
- [ "asc", "ascending", "desc", "descending", "gt", "lt", "gte",
27
- "lte", "ne", "near", "in", "nin", "mod", "all", "size", "exists",
28
- "within", ["matches","elemMatch"] ].each do |oper|
27
+ # Define all the necessary methods on symbol to support Mongoid's
28
+ # complex criterion.
29
+ #
30
+ # @example A greater than criterion.
31
+ # :field.gt => 5
32
+ #
33
+ # @return [ Criterion::Complex ] The criterion.
34
+ #
35
+ # @since 1.0.0
36
+ [
37
+ "all",
38
+ "asc",
39
+ "ascending",
40
+ "desc",
41
+ "descending",
42
+ "exists",
43
+ "gt",
44
+ "gte",
45
+ "in",
46
+ "lt",
47
+ "lte",
48
+ "mod",
49
+ "ne",
50
+ "near",
51
+ "nin",
52
+ "size",
53
+ "within",
54
+ ["matches","elemMatch"] ].each do |oper|
29
55
  m, oper = oper
30
56
  oper = m unless oper
31
57
  class_eval <<-OPERATORS
@@ -2,7 +2,20 @@
2
2
  module Mongoid #:nodoc:
3
3
  module Extensions #:nodoc:
4
4
  module TrueClass #:nodoc:
5
- module Equality #:nodoc:
5
+
6
+ # Adds equality hooks for true values.
7
+ module Equality
8
+
9
+ # Is the passed value a boolean?
10
+ #
11
+ # @example Is the value a boolean type?
12
+ # true.is_a?(Boolean)
13
+ #
14
+ # @param [ Class ] other The class to check.
15
+ #
16
+ # @return [ true, false ] If the other is a boolean.
17
+ #
18
+ # @since 1.0.0
6
19
  def is_a?(other)
7
20
  return true if other.name == "Boolean"
8
21
  super(other)
@@ -1,23 +1,25 @@
1
1
  # encoding: utf-8
2
2
  module Mongoid #:nodoc:
3
- module Extras #:nodoc:
3
+
4
+ # Adds support for caching queries at the class level.
5
+ module Extras
4
6
  extend ActiveSupport::Concern
7
+
5
8
  included do
6
- class_attribute :cached, :enslaved
9
+ class_attribute :cached
7
10
  self.cached = false
8
- self.enslaved = false
9
- delegate :cached?, :enslaved?, :to => "self.class"
11
+ delegate :cached?, :to => "self.class"
10
12
  end
11
13
 
12
14
  module ClassMethods #:nodoc
15
+
13
16
  # Sets caching on for this class. This class level configuration will
14
17
  # default all queries to cache the results of the first iteration over
15
18
  # the cursor into an internal array. This should only be used for queries
16
19
  # that return a small number of results or have small documents, as after
17
20
  # the first iteration the entire results will be stored in memory.
18
21
  #
19
- # Example:
20
- #
22
+ # @example Cache all reads for the class.
21
23
  # class Person
22
24
  # include Mongoid::Document
23
25
  # cache
@@ -28,34 +30,13 @@ module Mongoid #:nodoc:
28
30
 
29
31
  # Determines if the class is cached or not.
30
32
  #
31
- # Returns:
33
+ # @example Are class reads cached?
34
+ # Document.cached?
32
35
  #
33
- # True if cached, false if not.
36
+ # @return [ true, false ] If the reads are cached.
34
37
  def cached?
35
38
  !!self.cached
36
39
  end
37
-
38
- # Set whether or not this documents read operations should delegate to
39
- # the slave database by default.
40
- #
41
- # Example:
42
- #
43
- # class Person
44
- # include Mongoid::Document
45
- # enslave
46
- # end
47
- def enslave
48
- self.enslaved = true
49
- end
50
-
51
- # Determines if the class is enslaved or not.
52
- #
53
- # Returns:
54
- #
55
- # True if enslaved, false if not.
56
- def enslaved?
57
- !!self.enslaved
58
- end
59
40
  end
60
41
  end
61
42
  end
@@ -16,7 +16,7 @@ module Mongoid #:nodoc:
16
16
  # @return [ Document ] The instantiated document.
17
17
  def build(klass, attributes = {})
18
18
  type = (attributes || {})["_type"]
19
- type.blank? ? klass.new(attributes) : type.constantize.new(attributes)
19
+ (type && klass._types.include?(type)) ? type.constantize.new(attributes) : klass.new(attributes)
20
20
  end
21
21
 
22
22
  # Builds a new +Document+ from the supplied attributes loaded from the
@@ -1,4 +1,29 @@
1
1
  # encoding: utf-8
2
+ require "mongoid/fields/mappings"
3
+ require "mongoid/fields/serializable"
4
+ require "mongoid/fields/serializable/timekeeping"
5
+ require "mongoid/fields/serializable/array"
6
+ require "mongoid/fields/serializable/big_decimal"
7
+ require "mongoid/fields/serializable/binary"
8
+ require "mongoid/fields/serializable/boolean"
9
+ require "mongoid/fields/serializable/date"
10
+ require "mongoid/fields/serializable/date_time"
11
+ require "mongoid/fields/serializable/float"
12
+ require "mongoid/fields/serializable/hash"
13
+ require "mongoid/fields/serializable/integer"
14
+ require "mongoid/fields/serializable/bignum"
15
+ require "mongoid/fields/serializable/fixnum"
16
+ require "mongoid/fields/serializable/object"
17
+ require "mongoid/fields/serializable/object_id"
18
+ require "mongoid/fields/serializable/range"
19
+ require "mongoid/fields/serializable/set"
20
+ require "mongoid/fields/serializable/string"
21
+ require "mongoid/fields/serializable/symbol"
22
+ require "mongoid/fields/serializable/time"
23
+ require "mongoid/fields/serializable/time_with_zone"
24
+ require "mongoid/fields/serializable/foreign_keys/array"
25
+ require "mongoid/fields/serializable/foreign_keys/object"
26
+
2
27
  module Mongoid #:nodoc
3
28
 
4
29
  # This module defines behaviour for fields.
@@ -17,8 +42,61 @@ module Mongoid #:nodoc
17
42
  alias :id= :_id=
18
43
  end
19
44
 
45
+ class << self
46
+
47
+ # Stores the provided block to be run when the option name specified is
48
+ # defined on a field.
49
+ #
50
+ # No assumptions are made about what sort of work the handler might
51
+ # perform, so it will always be called if the `option_name` key is
52
+ # provided in the field definition -- even if it is false or nil.
53
+ #
54
+ # @example
55
+ # Mongoid::Fields.option :required do |model, field, value|
56
+ # model.validates_presence_of field if value
57
+ # end
58
+ #
59
+ # @param [ Symbol ] option_name the option name to match against
60
+ # @param [ Proc ] block the handler to execute when the option is
61
+ # provided.
62
+ #
63
+ # @since 2.1.0
64
+ def option(option_name, &block)
65
+ options[option_name] = block
66
+ end
67
+
68
+ # Return a map of custom option names to their handlers.
69
+ #
70
+ # @example
71
+ # Mongoid::Fields.options
72
+ # # => { :required => #<Proc:0x00000100976b38> }
73
+ #
74
+ # @return [ Hash ] the option map
75
+ #
76
+ # @since 2.1.0
77
+ def options
78
+ @options ||= {}
79
+ end
80
+ end
81
+
20
82
  module ClassMethods #:nodoc
21
83
 
84
+ # Returns the default values for the fields on the document.
85
+ #
86
+ # @example Get the defaults.
87
+ # Person.defaults
88
+ #
89
+ # @return [ Hash ] The field defaults.
90
+ def defaults
91
+ @defaults ||= {}.tap do |defs|
92
+ fields.each_pair do |field_name, field|
93
+ unless (default = field.default).nil?
94
+ defs[field_name.to_s] = default
95
+ end
96
+ end
97
+ end
98
+ end
99
+
22
100
  # Defines all the fields that are accessible on the Document
23
101
  # For each field that is defined, a getter and setter will be
24
102
  # added as an instance method to the Document.
@@ -35,8 +113,7 @@ module Mongoid #:nodoc
35
113
  #
36
114
  # @return [ Field ] The generated field
37
115
  def field(name, options = {})
38
- access = name.to_s
39
- set_field(access, options)
116
+ add_field(name.to_s, options)
40
117
  end
41
118
 
42
119
  # Return the fields for this class.
@@ -63,20 +140,6 @@ module Mongoid #:nodoc
63
140
  @fields = fields
64
141
  end
65
142
 
66
- # Returns the default values for the fields on the document.
67
- #
68
- # @example Get the defaults.
69
- # Person.defaults
70
- #
71
- # @return [ Hash ] The field defaults.
72
- def defaults
73
- fields.inject({}) do |defs, (field_name,field)|
74
- next(defs) if field.default.nil?
75
- defs[field_name.to_s] = field.default
76
- defs
77
- end
78
- end
79
-
80
143
  # When inheriting, we want to copy the fields from the parent class and
81
144
  # set the on the child to start, mimicking the behaviour of the old
82
145
  # class_inheritable_accessor that was deprecated in Rails edge.
@@ -92,44 +155,69 @@ module Mongoid #:nodoc
92
155
  subclass.fields = fields.dup
93
156
  end
94
157
 
158
+ # Replace a field with a new type.
159
+ #
160
+ # @example Replace the field.
161
+ # Model.replace_field("_id", String)
162
+ #
163
+ # @param [ String ] name The name of the field.
164
+ # @param [ Class ] type The new type of field.
165
+ #
166
+ # @return [ Serializable ] The new field.
167
+ #
168
+ # @since 2.1.0
169
+ def replace_field(name, type)
170
+ add_field(name, fields[name].options.merge(:type => type))
171
+ end
172
+
95
173
  protected
96
174
 
97
175
  # Define a field attribute for the +Document+.
98
176
  #
99
177
  # @example Set the field.
100
- # Person.set_field(:name, :default => "Test")
178
+ # Person.add_field(:name, :default => "Test")
101
179
  #
102
180
  # @param [ Symbol ] name The name of the field.
103
181
  # @param [ Hash ] options The hash of options.
104
- def set_field(name, options = {})
182
+ def add_field(name, options = {})
183
+ @defaults = nil if @defaults
184
+
105
185
  meth = options.delete(:as) || name
106
- Field.new(name, options).tap do |field|
186
+ Mappings.for(
187
+ options[:type], options[:identity]
188
+ ).new(name, options).tap do |field|
107
189
  fields[name] = field
108
190
  create_accessors(name, meth, options)
109
- add_dirty_methods(name)
110
191
  process_options(field)
192
+
193
+ # @todo Durran: Refactor this once we can depend on at least
194
+ # ActiveModel greater than 3.0.9. They finally have the ability then
195
+ # to add attribute methods one at a time. This code will make class
196
+ # load times extremely slow.
197
+ undefine_attribute_methods
198
+ define_attribute_methods(fields.keys)
111
199
  end
112
200
  end
113
201
 
114
- # Run through all custom options stored in Mongoid::Field.options and
202
+ # Run through all custom options stored in Mongoid::Fields.options and
115
203
  # execute the handler if the option is provided.
116
204
  #
117
205
  # @example
118
- # Mongoid::Field.option :custom do
206
+ # Mongoid::Fields.option :custom do
119
207
  # puts "called"
120
208
  # end
121
209
  #
122
- # field = Mongoid::Field.new(:test, :custom => true)
210
+ # field = Mongoid::Fields.new(:test, :custom => true)
123
211
  # Person.process_options(field)
124
212
  # # => "called"
125
213
  #
126
214
  # @param [ Field ] field the field to process
127
215
  def process_options(field)
128
- options = field.options
216
+ field_options = field.options
129
217
 
130
- Field.options.each do |option_name, handler|
131
- if options.has_key?(option_name)
132
- handler.call(self, field, options[option_name])
218
+ Fields.options.each_pair do |option_name, handler|
219
+ if field_options.has_key?(option_name)
220
+ handler.call(self, field, field_options[option_name])
133
221
  end
134
222
  end
135
223
  end
@@ -150,11 +238,15 @@ module Mongoid #:nodoc
150
238
  generated_field_methods.module_eval do
151
239
  if field.cast_on_read?
152
240
  define_method(meth) do
153
- field.get(read_attribute(name))
241
+ field.deserialize(read_attribute(name))
154
242
  end
155
243
  else
156
244
  define_method(meth) do
157
- read_attribute(name)
245
+ value = read_attribute(name)
246
+ if value.is_a?(Array) || value.is_a?(Hash)
247
+ changed_attributes[name] = value.clone unless attribute_changed?(name)
248
+ end
249
+ value
158
250
  end
159
251
  end
160
252
  define_method("#{meth}=") do |value|