mongoid-braxton 2.0.2

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 (226) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +50 -0
  3. data/Rakefile +51 -0
  4. data/lib/config/locales/bg.yml +41 -0
  5. data/lib/config/locales/de.yml +41 -0
  6. data/lib/config/locales/en.yml +45 -0
  7. data/lib/config/locales/es.yml +41 -0
  8. data/lib/config/locales/fr.yml +42 -0
  9. data/lib/config/locales/hu.yml +44 -0
  10. data/lib/config/locales/id.yml +46 -0
  11. data/lib/config/locales/it.yml +39 -0
  12. data/lib/config/locales/ja.yml +40 -0
  13. data/lib/config/locales/kr.yml +65 -0
  14. data/lib/config/locales/nl.yml +39 -0
  15. data/lib/config/locales/pl.yml +39 -0
  16. data/lib/config/locales/pt-BR.yml +40 -0
  17. data/lib/config/locales/pt.yml +40 -0
  18. data/lib/config/locales/ro.yml +46 -0
  19. data/lib/config/locales/ru.yml +41 -0
  20. data/lib/config/locales/sv.yml +40 -0
  21. data/lib/config/locales/vi.yml +45 -0
  22. data/lib/config/locales/zh-CN.yml +33 -0
  23. data/lib/mongoid.rb +140 -0
  24. data/lib/mongoid/atomicity.rb +111 -0
  25. data/lib/mongoid/attributes.rb +185 -0
  26. data/lib/mongoid/attributes/processing.rb +145 -0
  27. data/lib/mongoid/callbacks.rb +23 -0
  28. data/lib/mongoid/collection.rb +137 -0
  29. data/lib/mongoid/collections.rb +71 -0
  30. data/lib/mongoid/collections/master.rb +37 -0
  31. data/lib/mongoid/collections/operations.rb +42 -0
  32. data/lib/mongoid/collections/retry.rb +39 -0
  33. data/lib/mongoid/components.rb +45 -0
  34. data/lib/mongoid/config.rb +349 -0
  35. data/lib/mongoid/config/database.rb +167 -0
  36. data/lib/mongoid/config/replset_database.rb +78 -0
  37. data/lib/mongoid/contexts.rb +19 -0
  38. data/lib/mongoid/contexts/enumerable.rb +275 -0
  39. data/lib/mongoid/contexts/enumerable/sort.rb +43 -0
  40. data/lib/mongoid/contexts/mongo.rb +345 -0
  41. data/lib/mongoid/copyable.rb +46 -0
  42. data/lib/mongoid/criteria.rb +357 -0
  43. data/lib/mongoid/criterion/builder.rb +34 -0
  44. data/lib/mongoid/criterion/complex.rb +34 -0
  45. data/lib/mongoid/criterion/creational.rb +34 -0
  46. data/lib/mongoid/criterion/exclusion.rb +108 -0
  47. data/lib/mongoid/criterion/inclusion.rb +198 -0
  48. data/lib/mongoid/criterion/inspection.rb +22 -0
  49. data/lib/mongoid/criterion/optional.rb +193 -0
  50. data/lib/mongoid/criterion/selector.rb +143 -0
  51. data/lib/mongoid/criterion/unconvertable.rb +20 -0
  52. data/lib/mongoid/cursor.rb +86 -0
  53. data/lib/mongoid/default_scope.rb +36 -0
  54. data/lib/mongoid/dirty.rb +253 -0
  55. data/lib/mongoid/document.rb +284 -0
  56. data/lib/mongoid/errors.rb +13 -0
  57. data/lib/mongoid/errors/document_not_found.rb +29 -0
  58. data/lib/mongoid/errors/invalid_collection.rb +19 -0
  59. data/lib/mongoid/errors/invalid_database.rb +20 -0
  60. data/lib/mongoid/errors/invalid_field.rb +19 -0
  61. data/lib/mongoid/errors/invalid_options.rb +16 -0
  62. data/lib/mongoid/errors/invalid_type.rb +26 -0
  63. data/lib/mongoid/errors/mixed_relations.rb +37 -0
  64. data/lib/mongoid/errors/mongoid_error.rb +27 -0
  65. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +21 -0
  66. data/lib/mongoid/errors/unsaved_document.rb +23 -0
  67. data/lib/mongoid/errors/unsupported_version.rb +21 -0
  68. data/lib/mongoid/errors/validations.rb +24 -0
  69. data/lib/mongoid/extensions.rb +123 -0
  70. data/lib/mongoid/extensions/array/conversions.rb +23 -0
  71. data/lib/mongoid/extensions/array/parentization.rb +13 -0
  72. data/lib/mongoid/extensions/big_decimal/conversions.rb +19 -0
  73. data/lib/mongoid/extensions/binary/conversions.rb +17 -0
  74. data/lib/mongoid/extensions/boolean/conversions.rb +27 -0
  75. data/lib/mongoid/extensions/date/conversions.rb +25 -0
  76. data/lib/mongoid/extensions/datetime/conversions.rb +12 -0
  77. data/lib/mongoid/extensions/false_class/equality.rb +13 -0
  78. data/lib/mongoid/extensions/float/conversions.rb +20 -0
  79. data/lib/mongoid/extensions/hash/conversions.rb +19 -0
  80. data/lib/mongoid/extensions/hash/criteria_helpers.rb +22 -0
  81. data/lib/mongoid/extensions/hash/scoping.rb +12 -0
  82. data/lib/mongoid/extensions/integer/conversions.rb +20 -0
  83. data/lib/mongoid/extensions/nil/collectionization.rb +12 -0
  84. data/lib/mongoid/extensions/object/checks.rb +32 -0
  85. data/lib/mongoid/extensions/object/conversions.rb +25 -0
  86. data/lib/mongoid/extensions/object/reflections.rb +17 -0
  87. data/lib/mongoid/extensions/object/yoda.rb +27 -0
  88. data/lib/mongoid/extensions/object_id/conversions.rb +96 -0
  89. data/lib/mongoid/extensions/proc/scoping.rb +12 -0
  90. data/lib/mongoid/extensions/range/conversions.rb +25 -0
  91. data/lib/mongoid/extensions/set/conversions.rb +20 -0
  92. data/lib/mongoid/extensions/string/conversions.rb +34 -0
  93. data/lib/mongoid/extensions/string/inflections.rb +97 -0
  94. data/lib/mongoid/extensions/symbol/conversions.rb +21 -0
  95. data/lib/mongoid/extensions/symbol/inflections.rb +40 -0
  96. data/lib/mongoid/extensions/time_conversions.rb +38 -0
  97. data/lib/mongoid/extensions/true_class/equality.rb +13 -0
  98. data/lib/mongoid/extras.rb +42 -0
  99. data/lib/mongoid/factory.rb +37 -0
  100. data/lib/mongoid/field.rb +162 -0
  101. data/lib/mongoid/fields.rb +183 -0
  102. data/lib/mongoid/finders.rb +127 -0
  103. data/lib/mongoid/hierarchy.rb +85 -0
  104. data/lib/mongoid/identity.rb +92 -0
  105. data/lib/mongoid/indexes.rb +38 -0
  106. data/lib/mongoid/inspection.rb +54 -0
  107. data/lib/mongoid/javascript.rb +21 -0
  108. data/lib/mongoid/javascript/functions.yml +37 -0
  109. data/lib/mongoid/json.rb +16 -0
  110. data/lib/mongoid/keys.rb +131 -0
  111. data/lib/mongoid/logger.rb +18 -0
  112. data/lib/mongoid/matchers.rb +32 -0
  113. data/lib/mongoid/matchers/all.rb +11 -0
  114. data/lib/mongoid/matchers/default.rb +70 -0
  115. data/lib/mongoid/matchers/exists.rb +13 -0
  116. data/lib/mongoid/matchers/gt.rb +11 -0
  117. data/lib/mongoid/matchers/gte.rb +11 -0
  118. data/lib/mongoid/matchers/in.rb +11 -0
  119. data/lib/mongoid/matchers/lt.rb +11 -0
  120. data/lib/mongoid/matchers/lte.rb +11 -0
  121. data/lib/mongoid/matchers/ne.rb +11 -0
  122. data/lib/mongoid/matchers/nin.rb +11 -0
  123. data/lib/mongoid/matchers/or.rb +30 -0
  124. data/lib/mongoid/matchers/size.rb +11 -0
  125. data/lib/mongoid/matchers/strategies.rb +63 -0
  126. data/lib/mongoid/multi_database.rb +11 -0
  127. data/lib/mongoid/multi_parameter_attributes.rb +82 -0
  128. data/lib/mongoid/named_scope.rb +137 -0
  129. data/lib/mongoid/nested_attributes.rb +51 -0
  130. data/lib/mongoid/observer.rb +67 -0
  131. data/lib/mongoid/paranoia.rb +103 -0
  132. data/lib/mongoid/paths.rb +61 -0
  133. data/lib/mongoid/persistence.rb +240 -0
  134. data/lib/mongoid/persistence/atomic.rb +88 -0
  135. data/lib/mongoid/persistence/atomic/add_to_set.rb +32 -0
  136. data/lib/mongoid/persistence/atomic/inc.rb +28 -0
  137. data/lib/mongoid/persistence/atomic/operation.rb +44 -0
  138. data/lib/mongoid/persistence/atomic/pull_all.rb +33 -0
  139. data/lib/mongoid/persistence/atomic/push.rb +28 -0
  140. data/lib/mongoid/persistence/command.rb +71 -0
  141. data/lib/mongoid/persistence/insert.rb +53 -0
  142. data/lib/mongoid/persistence/insert_embedded.rb +43 -0
  143. data/lib/mongoid/persistence/remove.rb +44 -0
  144. data/lib/mongoid/persistence/remove_all.rb +40 -0
  145. data/lib/mongoid/persistence/remove_embedded.rb +48 -0
  146. data/lib/mongoid/persistence/update.rb +77 -0
  147. data/lib/mongoid/railtie.rb +139 -0
  148. data/lib/mongoid/railties/database.rake +171 -0
  149. data/lib/mongoid/railties/document.rb +12 -0
  150. data/lib/mongoid/relations.rb +107 -0
  151. data/lib/mongoid/relations/accessors.rb +175 -0
  152. data/lib/mongoid/relations/auto_save.rb +34 -0
  153. data/lib/mongoid/relations/binding.rb +26 -0
  154. data/lib/mongoid/relations/bindings.rb +9 -0
  155. data/lib/mongoid/relations/bindings/embedded/in.rb +82 -0
  156. data/lib/mongoid/relations/bindings/embedded/many.rb +98 -0
  157. data/lib/mongoid/relations/bindings/embedded/one.rb +66 -0
  158. data/lib/mongoid/relations/bindings/referenced/in.rb +74 -0
  159. data/lib/mongoid/relations/bindings/referenced/many.rb +96 -0
  160. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +103 -0
  161. data/lib/mongoid/relations/bindings/referenced/one.rb +66 -0
  162. data/lib/mongoid/relations/builder.rb +42 -0
  163. data/lib/mongoid/relations/builders.rb +79 -0
  164. data/lib/mongoid/relations/builders/embedded/in.rb +25 -0
  165. data/lib/mongoid/relations/builders/embedded/many.rb +32 -0
  166. data/lib/mongoid/relations/builders/embedded/one.rb +26 -0
  167. data/lib/mongoid/relations/builders/nested_attributes/many.rb +126 -0
  168. data/lib/mongoid/relations/builders/nested_attributes/one.rb +135 -0
  169. data/lib/mongoid/relations/builders/referenced/in.rb +29 -0
  170. data/lib/mongoid/relations/builders/referenced/many.rb +47 -0
  171. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +29 -0
  172. data/lib/mongoid/relations/builders/referenced/one.rb +27 -0
  173. data/lib/mongoid/relations/cascading.rb +55 -0
  174. data/lib/mongoid/relations/cascading/delete.rb +19 -0
  175. data/lib/mongoid/relations/cascading/destroy.rb +19 -0
  176. data/lib/mongoid/relations/cascading/nullify.rb +18 -0
  177. data/lib/mongoid/relations/cascading/strategy.rb +26 -0
  178. data/lib/mongoid/relations/constraint.rb +42 -0
  179. data/lib/mongoid/relations/cyclic.rb +103 -0
  180. data/lib/mongoid/relations/embedded/atomic.rb +86 -0
  181. data/lib/mongoid/relations/embedded/atomic/operation.rb +63 -0
  182. data/lib/mongoid/relations/embedded/atomic/pull.rb +65 -0
  183. data/lib/mongoid/relations/embedded/atomic/push_all.rb +59 -0
  184. data/lib/mongoid/relations/embedded/atomic/set.rb +61 -0
  185. data/lib/mongoid/relations/embedded/atomic/unset.rb +41 -0
  186. data/lib/mongoid/relations/embedded/in.rb +173 -0
  187. data/lib/mongoid/relations/embedded/many.rb +499 -0
  188. data/lib/mongoid/relations/embedded/one.rb +170 -0
  189. data/lib/mongoid/relations/macros.rb +310 -0
  190. data/lib/mongoid/relations/many.rb +215 -0
  191. data/lib/mongoid/relations/metadata.rb +539 -0
  192. data/lib/mongoid/relations/nested_builder.rb +68 -0
  193. data/lib/mongoid/relations/one.rb +47 -0
  194. data/lib/mongoid/relations/polymorphic.rb +54 -0
  195. data/lib/mongoid/relations/proxy.rb +143 -0
  196. data/lib/mongoid/relations/referenced/batch.rb +71 -0
  197. data/lib/mongoid/relations/referenced/batch/insert.rb +57 -0
  198. data/lib/mongoid/relations/referenced/in.rb +216 -0
  199. data/lib/mongoid/relations/referenced/many.rb +516 -0
  200. data/lib/mongoid/relations/referenced/many_to_many.rb +396 -0
  201. data/lib/mongoid/relations/referenced/one.rb +222 -0
  202. data/lib/mongoid/relations/reflections.rb +45 -0
  203. data/lib/mongoid/safe.rb +23 -0
  204. data/lib/mongoid/safety.rb +207 -0
  205. data/lib/mongoid/scope.rb +31 -0
  206. data/lib/mongoid/serialization.rb +99 -0
  207. data/lib/mongoid/sharding.rb +51 -0
  208. data/lib/mongoid/state.rb +67 -0
  209. data/lib/mongoid/timestamps.rb +14 -0
  210. data/lib/mongoid/timestamps/created.rb +31 -0
  211. data/lib/mongoid/timestamps/updated.rb +33 -0
  212. data/lib/mongoid/validations.rb +124 -0
  213. data/lib/mongoid/validations/associated.rb +44 -0
  214. data/lib/mongoid/validations/referenced.rb +58 -0
  215. data/lib/mongoid/validations/uniqueness.rb +85 -0
  216. data/lib/mongoid/version.rb +4 -0
  217. data/lib/mongoid/versioning.rb +113 -0
  218. data/lib/rails/generators/mongoid/config/config_generator.rb +25 -0
  219. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +20 -0
  220. data/lib/rails/generators/mongoid/model/model_generator.rb +24 -0
  221. data/lib/rails/generators/mongoid/model/templates/model.rb +19 -0
  222. data/lib/rails/generators/mongoid/observer/observer_generator.rb +17 -0
  223. data/lib/rails/generators/mongoid/observer/templates/observer.rb +4 -0
  224. data/lib/rails/generators/mongoid_generator.rb +70 -0
  225. data/lib/rails/mongoid.rb +58 -0
  226. metadata +406 -0
@@ -0,0 +1,33 @@
1
+ zh-CN:
2
+ mongoid:
3
+ errors:
4
+ messages:
5
+ blank:
6
+ 不能为空
7
+ taken:
8
+ 已占用
9
+ document_not_found:
10
+ 没有发现类是%{klass}id(s)是%{identifiers}的文档
11
+ invalid_database:
12
+ 数据库应该是Mongo::DB,而不是%{name}.
13
+ invalid_type:
14
+ 在类%{klass}中定义了字段,实际值是%{value}的%{other}.
15
+ unsupported_version:
16
+ MongoDB %{version} 版本已过期,请升级到 %{mongo_version}.
17
+ validations:
18
+ 校验失败 - %{errors}.
19
+ invalid_collection:
20
+ 不允许直接访问嵌入式的集合%{klass} , 请从文档的根访问集合.
21
+ invalid_field:
22
+ 字段的名字不允许为 %{name}. 你不应该定义跟Mongoid内部属性或者方法相同的名字,详细请看Use Document#instance_methods.
23
+ too_many_nested_attribute_records:
24
+ 被关联的%{association} 嵌入式属性不能超过 %{limit}.
25
+ embedded_in_must_have_inverse_of:
26
+ embedded_in的关联属性必须包含inverse_of.
27
+ dependent_only_references_one_or_many:
28
+ dependent => destroy|delete 选项只有在references_one或者references_many时候有效.
29
+ association_cant_have_inverse_of:
30
+ 在当前的关联中,不允许定义inverse_of去,其只有在embedded_in或者references_many是数组的情况下使用
31
+ unsaved_document:
32
+ You cannot call create or create! through a relational association
33
+ relation (%{document}) who's parent (%{base}) is not already saved.
data/lib/mongoid.rb ADDED
@@ -0,0 +1,140 @@
1
+ # encoding: utf-8
2
+
3
+ # Copyright (c) 2009 - 2011 Durran Jordan and friends.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ require "delegate"
24
+ require "time"
25
+ require "ostruct"
26
+ require "active_support/core_ext"
27
+ require 'active_support/json'
28
+ require "active_support/inflector"
29
+ require "active_support/time_with_zone"
30
+ require "active_model"
31
+ require "active_model/callbacks"
32
+ require "active_model/conversion"
33
+ require "active_model/errors"
34
+ require "active_model/mass_assignment_security"
35
+ require "active_model/naming"
36
+ require "active_model/serialization"
37
+ require "active_model/translation"
38
+ require "active_model/validator"
39
+ require "active_model/validations"
40
+ require "mongo"
41
+ require "mongoid/errors"
42
+ require "mongoid/extensions"
43
+ require "mongoid/safe"
44
+ require "mongoid/relations"
45
+ require "mongoid/atomicity"
46
+ require "mongoid/attributes"
47
+ require "mongoid/callbacks"
48
+ require "mongoid/collection"
49
+ require "mongoid/collections"
50
+ require "mongoid/config"
51
+ require "mongoid/contexts"
52
+ require "mongoid/copyable"
53
+ require "mongoid/criteria"
54
+ require "mongoid/cursor"
55
+ require "mongoid/default_scope"
56
+ require "mongoid/dirty"
57
+ require "mongoid/extras"
58
+ require "mongoid/factory"
59
+ require "mongoid/field"
60
+ require "mongoid/fields"
61
+ require "mongoid/finders"
62
+ require "mongoid/hierarchy"
63
+ require "mongoid/identity"
64
+ require "mongoid/indexes"
65
+ require "mongoid/inspection"
66
+ require "mongoid/javascript"
67
+ require "mongoid/json"
68
+ require "mongoid/keys"
69
+ require "mongoid/logger"
70
+ require "mongoid/matchers"
71
+ require "mongoid/multi_parameter_attributes"
72
+ require "mongoid/multi_database"
73
+ require "mongoid/named_scope"
74
+ require "mongoid/nested_attributes"
75
+ require "mongoid/observer"
76
+ require "mongoid/paths"
77
+ require "mongoid/persistence"
78
+ require "mongoid/safety"
79
+ require "mongoid/scope"
80
+ require "mongoid/serialization"
81
+ require "mongoid/sharding"
82
+ require "mongoid/state"
83
+ require "mongoid/timestamps"
84
+ require "mongoid/validations"
85
+ require "mongoid/versioning"
86
+ require "mongoid/components"
87
+ require "mongoid/paranoia"
88
+ require "mongoid/document"
89
+
90
+ # add railtie
91
+ if defined?(Rails)
92
+ require "mongoid/railtie"
93
+ end
94
+
95
+ # add english load path by default
96
+ I18n.load_path << File.join(File.dirname(__FILE__), "config", "locales", "en.yml")
97
+
98
+ module Mongoid #:nodoc
99
+
100
+ MONGODB_VERSION = "1.6.0"
101
+
102
+ class << self
103
+
104
+ # Sets the Mongoid configuration options. Best used by passing a block.
105
+ #
106
+ # @example Set up configuration options.
107
+ #
108
+ # Mongoid.configure do |config|
109
+ # name = "mongoid_test"
110
+ # host = "localhost"
111
+ # config.allow_dynamic_fields = false
112
+ # config.master = Mongo::Connection.new.db(name)
113
+ # config.slaves = [
114
+ # Mongo::Connection.new(host, 27018, :slave_ok => true).db(name),
115
+ # Mongo::Connection.new(host, 27019, :slave_ok => true).db(name)
116
+ # ]
117
+ # end
118
+ #
119
+ # @return [ Config ] The configuration obejct.
120
+ def configure
121
+ config = Mongoid::Config
122
+ block_given? ? yield(config) : config
123
+ end
124
+ alias :config :configure
125
+ end
126
+
127
+ # Take all the public instance methods from the Config singleton and allow
128
+ # them to be accessed through the Mongoid module directly.
129
+ #
130
+ # @example Delegate the configuration methods.
131
+ # Mongoid.database = Mongo::Connection.new.db("test")
132
+ (Mongoid::Config.public_instance_methods(false) +
133
+ ActiveModel::Observing::ClassMethods.public_instance_methods(false)).each do |name|
134
+ (class << self; self; end).class_eval <<-EOT
135
+ def #{name}(*args)
136
+ configure.send("#{name}", *args)
137
+ end
138
+ EOT
139
+ end
140
+ end
@@ -0,0 +1,111 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+
4
+ # This module contains the logic for supporting atomic operations against the
5
+ # database.
6
+ #
7
+ # @todo Durran: Refactor class out into separate objects for each type of
8
+ # update.
9
+ module Atomicity
10
+ extend ActiveSupport::Concern
11
+
12
+ # Get all the atomic updates that need to happen for the current
13
+ # +Document+. This includes all changes that need to happen in the
14
+ # entire hierarchy that exists below where the save call was made.
15
+ #
16
+ # @note
17
+ # MongoDB does not allow "conflicting modifications" to be
18
+ # performed in a single operation. Conflicting modifications are
19
+ # detected by the 'haveConflictingMod' function in MongoDB.
20
+ # Examination of the code suggests that two modifications (a $set
21
+ # and a $pushAll, for example) conflict if:
22
+ # (1) the key paths being modified are equal.
23
+ # (2) one key path is a prefix of the other.
24
+ # So a $set of 'addresses.0.street' will conflict with a $pushAll
25
+ # to 'addresses', and we will need to split our update into two
26
+ # pieces. We do not, however, attempt to match MongoDB's logic
27
+ # exactly. Instead, we assume that two updates conflict if the
28
+ # first component of the two key paths matches.
29
+ #
30
+ # @example Get the updates that need to occur.
31
+ # person._updates
32
+ #
33
+ # @return [ Hash ] The updates and their modifiers.
34
+ def _updates
35
+ processed = {}
36
+
37
+ _children.inject({ "$set" => _sets, "$pushAll" => {}, :other => {} }) do |updates, child|
38
+ changes = child._sets
39
+ updates["$set"].update(changes)
40
+ unless changes.empty?
41
+ processed[child._conflicting_modification_key] = true
42
+ end
43
+
44
+ if processed.has_key?(child._conflicting_modification_key)
45
+ target = :other
46
+ else
47
+ target = "$pushAll"
48
+ end
49
+
50
+ child._pushes.each do |attr, val|
51
+ if updates[target].has_key?(attr)
52
+ updates[target][attr] << val
53
+ else
54
+ updates[target].update({attr => [val]})
55
+ end
56
+ end
57
+ updates
58
+ end.delete_if do |key, value|
59
+ value.empty?
60
+ end
61
+ end
62
+
63
+ protected
64
+
65
+ # Get the key used to check for conflicting modifications. For now, we
66
+ # just use the first component of _path, and discard the first period
67
+ # and everything that follows.
68
+ #
69
+ # @example Get the key.
70
+ # person._conflicting_modification_key
71
+ #
72
+ # @return [ String ] The conflicting key.
73
+ def _conflicting_modification_key
74
+ _path.sub(/\..*/, '')
75
+ end
76
+
77
+ # Get all the push attributes that need to occur.
78
+ #
79
+ # @example Get the pushes.
80
+ # person._pushes
81
+ #
82
+ # @return [ Hash ] The $pushAll operations.
83
+ def _pushes
84
+ pushable? ? { _path => as_document } : {}
85
+ end
86
+
87
+ # Determine if the document can be pushed.
88
+ #
89
+ # @example Is this pushable?
90
+ # person.pushable?
91
+ #
92
+ # @return [ true, false ] Is the document new and embedded?
93
+ def pushable?
94
+ new_record? && embedded_many? && _parent.persisted?
95
+ end
96
+
97
+ # Get all the attributes that need to be set.
98
+ #
99
+ # @example Get the sets.
100
+ # person._sets
101
+ #
102
+ # @return [ Hash ] The $set operations.
103
+ def _sets
104
+ if changed? && !new_record?
105
+ setters
106
+ else
107
+ embedded_one? && new_record? ? { _path => as_document } : {}
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,185 @@
1
+ # encoding: utf-8
2
+ require "mongoid/attributes/processing"
3
+
4
+ module Mongoid #:nodoc:
5
+
6
+ # This module contains the logic for handling the internal attributes hash,
7
+ # and how to get and set values.
8
+ module Attributes
9
+ include Processing
10
+
11
+ attr_reader :attributes
12
+ alias :raw_attributes :attributes
13
+
14
+ # Determine if an attribute is present.
15
+ #
16
+ # @example Is the attribute present?
17
+ # person.attribute_present?("title")
18
+ #
19
+ # @param [ String, Symbol ] name The name of the attribute.
20
+ #
21
+ # @return [ true, false ] True if present, false if not.
22
+ #
23
+ # @since 1.0.0
24
+ def attribute_present?(name)
25
+ !read_attribute(name).blank?
26
+ end
27
+
28
+ # Read a value from the document attributes. If the value does not exist
29
+ # it will return nil.
30
+ #
31
+ # @example Read an attribute.
32
+ # person.read_attribute(:title)
33
+ #
34
+ # @example Read an attribute (alternate syntax.)
35
+ # person[:title]
36
+ #
37
+ # @param [ String, Symbol ] name The name of the attribute to get.
38
+ #
39
+ # @return [ Object ] The value of the attribute.
40
+ #
41
+ # @since 1.0.0
42
+ def read_attribute(name)
43
+ access = name.to_s
44
+ value = attributes[access]
45
+ accessed(access, value)
46
+ end
47
+ alias :[] :read_attribute
48
+
49
+ # Remove a value from the +Document+ attributes. If the value does not exist
50
+ # it will fail gracefully.
51
+ #
52
+ # @example Remove the attribute.
53
+ # person.remove_attribute(:title)
54
+ #
55
+ # @param [ String, Symbol ] name The name of the attribute to remove.
56
+ #
57
+ # @since 1.0.0
58
+ def remove_attribute(name)
59
+ access = name.to_s
60
+ modify(access, attributes.delete(access), nil)
61
+ end
62
+
63
+ # Override respond_to? so it responds properly for dynamic attributes.
64
+ #
65
+ # @example Does this object respond to the method?
66
+ # person.respond_to?(:title)
67
+ #
68
+ # @param [ Array ] *args The name of the method.
69
+ #
70
+ # @return [ true, false ] True if it does, false if not.
71
+ #
72
+ # @since 1.0.0
73
+ def respond_to?(*args)
74
+ (Mongoid.allow_dynamic_fields &&
75
+ attributes &&
76
+ attributes.has_key?(args.first.to_s)
77
+ ) || super
78
+ end
79
+
80
+ # Write a single attribute to the document attribute hash. This will
81
+ # also fire the before and after update callbacks, and perform any
82
+ # necessary typecasting.
83
+ #
84
+ # @example Write the attribute.
85
+ # person.write_attribute(:title, "Mr.")
86
+ #
87
+ # @example Write the attribute (alternate syntax.)
88
+ # person[:title] = "Mr."
89
+ #
90
+ # @param [ String, Symbol ] name The name of the attribute to update.
91
+ # @param [ Object ] value The value to set for the attribute.
92
+ #
93
+ # @since 1.0.0
94
+ def write_attribute(name, value)
95
+ access = name.to_s
96
+ modify(access, attributes[access], typed_value_for(access, value))
97
+ end
98
+ alias :[]= :write_attribute
99
+
100
+ # Writes the supplied attributes hash to the document. This will only
101
+ # overwrite existing attributes if they are present in the new +Hash+, all
102
+ # others will be preserved.
103
+ #
104
+ # @example Write the attributes.
105
+ # person.write_attributes(:title => "Mr.")
106
+ #
107
+ # @example Write the attributes (alternate syntax.)
108
+ # person.attributes = { :title => "Mr." }
109
+ #
110
+ # @param [ Hash ] attrs The new attributes to set.
111
+ # @param [ Boolean ] guard_protected_attributes False to skip mass assignment protection.
112
+ #
113
+ # @since 1.0.0
114
+ def write_attributes(attrs = nil, guard_protected_attributes = true)
115
+ process(attrs, guard_protected_attributes) do |document|
116
+ document.identify if new? && id.blank?
117
+ end
118
+ end
119
+ alias :attributes= :write_attributes
120
+
121
+ protected
122
+
123
+ # Get the default values for the attributes.
124
+ #
125
+ # @example Get the defaults.
126
+ # person.default_attributes
127
+ #
128
+ # @return [ Hash ] The default values for each field.
129
+ #
130
+ # @since 1.0.0
131
+ #
132
+ # @raise [ RuntimeError ] Always
133
+ # @since 2.0.0.rc.8
134
+ def default_attributes
135
+ raise "default_attributes is no longer valid. Plase use: apply_default_attributes."
136
+ end
137
+
138
+ # Set any missing default values in the attributes.
139
+ #
140
+ # @example Get the raw attributes after defaults have been applied.
141
+ # person.apply_default_attributes
142
+ #
143
+ # @return [ Hash ] The raw attributes.
144
+ #
145
+ # @since 2.0.0.rc.8
146
+ def apply_default_attributes
147
+ (@attributes ||= {}).tap do |h|
148
+ defaults.each_pair do |key, val|
149
+ unless h.has_key?(key)
150
+ h[key] = val.respond_to?(:call) ? typed_value_for(key, val.call) : val
151
+ end
152
+ end
153
+ end
154
+ end
155
+
156
+ # Used for allowing accessor methods for dynamic attributes.
157
+ #
158
+ # @param [ String, Symbol ] name The name of the method.
159
+ # @param [ Array ] *args The arguments to the method.
160
+ def method_missing(name, *args)
161
+ attr = name.to_s
162
+ return super unless attributes.has_key?(attr.reader)
163
+ if attr.writer?
164
+ write_attribute(attr.reader, (args.size > 1) ? args : args.first)
165
+ else
166
+ read_attribute(attr.reader)
167
+ end
168
+ end
169
+
170
+ # Return the typecasted value for a field.
171
+ #
172
+ # @example Get the value typecasted.
173
+ # person.typed_value_for(:title, :sir)
174
+ #
175
+ # @param [ String, Symbol ] key The field name.
176
+ # @param [ Object ] value The uncast value.
177
+ #
178
+ # @return [ Object ] The cast value.
179
+ #
180
+ # @since 1.0.0
181
+ def typed_value_for(key, value)
182
+ fields.has_key?(key) ? fields[key].set(value) : value
183
+ end
184
+ end
185
+ end