mongoid 2.3.5 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. data/CHANGELOG.md +34 -176
  2. data/LICENSE +1 -1
  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 +8 -0
  6. data/lib/config/locales/en.yml +8 -0
  7. data/lib/config/locales/es.yml +9 -3
  8. data/lib/config/locales/fr.yml +6 -0
  9. data/lib/config/locales/hi.yml +6 -0
  10. data/lib/config/locales/hu.yml +6 -0
  11. data/lib/config/locales/id.yml +6 -0
  12. data/lib/config/locales/it.yml +6 -0
  13. data/lib/config/locales/ja.yml +6 -0
  14. data/lib/config/locales/kr.yml +6 -0
  15. data/lib/config/locales/nl.yml +8 -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 +8 -2
  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 +14 -8
  23. data/lib/config/locales/zh-CN.yml +6 -0
  24. data/lib/mongoid/atomic.rb +62 -13
  25. data/lib/mongoid/atomic/modifiers.rb +33 -1
  26. data/lib/mongoid/attributes.rb +5 -19
  27. data/lib/mongoid/callbacks.rb +2 -1
  28. data/lib/mongoid/collection.rb +2 -2
  29. data/lib/mongoid/collections/retry.rb +18 -6
  30. data/lib/mongoid/components.rb +2 -0
  31. data/lib/mongoid/config.rb +8 -63
  32. data/lib/mongoid/config/environment.rb +41 -0
  33. data/lib/mongoid/config/options.rb +74 -0
  34. data/lib/mongoid/contexts/enumerable.rb +0 -24
  35. data/lib/mongoid/contexts/mongo.rb +33 -3
  36. data/lib/mongoid/copyable.rb +1 -1
  37. data/lib/mongoid/criteria.rb +4 -2
  38. data/lib/mongoid/criterion/inclusion.rb +1 -16
  39. data/lib/mongoid/criterion/optional.rb +37 -10
  40. data/lib/mongoid/criterion/scoping.rb +83 -0
  41. data/lib/mongoid/criterion/selector.rb +9 -6
  42. data/lib/mongoid/default_scope.rb +1 -1
  43. data/lib/mongoid/dirty.rb +163 -29
  44. data/lib/mongoid/document.rb +58 -7
  45. data/lib/mongoid/errors.rb +2 -0
  46. data/lib/mongoid/errors/no_environment.rb +19 -0
  47. data/lib/mongoid/errors/scope_overwrite.rb +21 -0
  48. data/lib/mongoid/extensions.rb +6 -0
  49. data/lib/mongoid/extensions/array/deep_copy.rb +25 -0
  50. data/lib/mongoid/extensions/hash/deep_copy.rb +25 -0
  51. data/lib/mongoid/extensions/hash/scoping.rb +1 -1
  52. data/lib/mongoid/extensions/object/deep_copy.rb +21 -0
  53. data/lib/mongoid/extensions/proc/scoping.rb +2 -2
  54. data/lib/mongoid/extensions/symbol/inflections.rb +1 -0
  55. data/lib/mongoid/fields.rb +171 -104
  56. data/lib/mongoid/fields/{serializable → internal}/array.rb +33 -1
  57. data/lib/mongoid/fields/{serializable → internal}/big_decimal.rb +16 -1
  58. data/lib/mongoid/fields/{serializable → internal}/bignum.rb +1 -1
  59. data/lib/mongoid/fields/{serializable → internal}/binary.rb +1 -1
  60. data/lib/mongoid/fields/{serializable → internal}/boolean.rb +16 -1
  61. data/lib/mongoid/fields/{serializable → internal}/date.rb +1 -1
  62. data/lib/mongoid/fields/{serializable → internal}/date_time.rb +1 -1
  63. data/lib/mongoid/fields/{serializable → internal}/fixnum.rb +1 -1
  64. data/lib/mongoid/fields/{serializable → internal}/float.rb +16 -1
  65. data/lib/mongoid/fields/internal/foreign_keys/array.rb +74 -0
  66. data/lib/mongoid/fields/{serializable → internal}/foreign_keys/object.rb +11 -2
  67. data/lib/mongoid/fields/{serializable → internal}/hash.rb +1 -1
  68. data/lib/mongoid/fields/{serializable → internal}/integer.rb +16 -1
  69. data/lib/mongoid/fields/{serializable → internal}/localized.rb +23 -2
  70. data/lib/mongoid/fields/{serializable → internal}/nil_class.rb +16 -1
  71. data/lib/mongoid/fields/{serializable → internal}/object.rb +1 -1
  72. data/lib/mongoid/fields/{serializable → internal}/object_id.rb +16 -1
  73. data/lib/mongoid/fields/{serializable → internal}/range.rb +21 -2
  74. data/lib/mongoid/fields/{serializable → internal}/set.rb +16 -1
  75. data/lib/mongoid/fields/{serializable → internal}/string.rb +16 -1
  76. data/lib/mongoid/fields/{serializable → internal}/symbol.rb +17 -1
  77. data/lib/mongoid/fields/{serializable → internal}/time.rb +1 -1
  78. data/lib/mongoid/fields/{serializable → internal}/time_with_zone.rb +1 -1
  79. data/lib/mongoid/fields/{serializable → internal}/timekeeping.rb +16 -1
  80. data/lib/mongoid/fields/mappings.rb +8 -3
  81. data/lib/mongoid/fields/serializable.rb +34 -3
  82. data/lib/mongoid/hierarchy.rb +14 -14
  83. data/lib/mongoid/identity_map.rb +3 -2
  84. data/lib/mongoid/logger.rb +1 -7
  85. data/lib/mongoid/named_scope.rb +16 -12
  86. data/lib/mongoid/observer.rb +5 -1
  87. data/lib/mongoid/paranoia.rb +1 -0
  88. data/lib/mongoid/persistence.rb +11 -4
  89. data/lib/mongoid/persistence/atomic.rb +4 -1
  90. data/lib/mongoid/persistence/atomic/add_to_set.rb +17 -1
  91. data/lib/mongoid/persistence/atomic/sets.rb +1 -1
  92. data/lib/mongoid/railties/database.rake +1 -1
  93. data/lib/mongoid/relations.rb +1 -3
  94. data/lib/mongoid/relations/auto_save.rb +1 -1
  95. data/lib/mongoid/relations/builders.rb +1 -1
  96. data/lib/mongoid/relations/builders/embedded/many.rb +2 -6
  97. data/lib/mongoid/relations/builders/nested_attributes/many.rb +1 -1
  98. data/lib/mongoid/relations/builders/nested_attributes/one.rb +1 -1
  99. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +1 -1
  100. data/lib/mongoid/relations/cascading/delete.rb +1 -1
  101. data/lib/mongoid/relations/cyclic.rb +10 -6
  102. data/lib/mongoid/relations/embedded/atomic.rb +3 -3
  103. data/lib/mongoid/relations/embedded/many.rb +98 -20
  104. data/lib/mongoid/relations/macros.rb +2 -0
  105. data/lib/mongoid/relations/many.rb +13 -0
  106. data/lib/mongoid/relations/metadata.rb +3 -3
  107. data/lib/mongoid/relations/nested_builder.rb +4 -3
  108. data/lib/mongoid/relations/proxy.rb +0 -1
  109. data/lib/mongoid/relations/referenced/batch.rb +3 -2
  110. data/lib/mongoid/relations/referenced/in.rb +3 -3
  111. data/lib/mongoid/relations/referenced/many.rb +89 -10
  112. data/lib/mongoid/relations/referenced/many_to_many.rb +34 -43
  113. data/lib/mongoid/relations/referenced/one.rb +8 -4
  114. data/lib/mongoid/relations/synchronization.rb +22 -5
  115. data/lib/mongoid/threaded.rb +38 -276
  116. data/lib/mongoid/threaded/lifecycle.rb +18 -18
  117. data/lib/mongoid/timestamps/updated.rb +13 -3
  118. data/lib/mongoid/validations.rb +22 -1
  119. data/lib/mongoid/validations/presence.rb +40 -0
  120. data/lib/mongoid/validations/uniqueness.rb +14 -3
  121. data/lib/mongoid/version.rb +1 -1
  122. data/lib/mongoid/versioning.rb +6 -2
  123. data/lib/rails/mongoid.rb +7 -1
  124. metadata +64 -45
  125. data/lib/mongoid/fields/serializable/foreign_keys/array.rb +0 -42
  126. data/lib/mongoid/relations/embedded/sort.rb +0 -31
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc
3
+ module Errors #:nodoc
4
+
5
+ # This error is raised when trying to create a scope with an name already
6
+ # taken by another scope or method
7
+ #
8
+ # @example Create the error.
9
+ # ScopeOverwrite.new(Person,'teenies')
10
+ class ScopeOverwrite < MongoidError
11
+ def initialize(model_name,scope_name)
12
+ super(
13
+ translate(
14
+ "scope_overwrite",
15
+ { :model_name => model_name, :scope_name => scope_name }
16
+ )
17
+ )
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,11 +1,14 @@
1
1
  # encoding: utf-8
2
+ require "mongoid/extensions/array/deep_copy"
2
3
  require "mongoid/extensions/array/deletion"
3
4
  require "mongoid/extensions/false_class/equality"
5
+ require "mongoid/extensions/hash/deep_copy"
4
6
  require "mongoid/extensions/hash/criteria_helpers"
5
7
  require "mongoid/extensions/hash/scoping"
6
8
  require "mongoid/extensions/integer/checks"
7
9
  require "mongoid/extensions/nil/collectionization"
8
10
  require "mongoid/extensions/object/checks"
11
+ require "mongoid/extensions/object/deep_copy"
9
12
  require "mongoid/extensions/object/reflections"
10
13
  require "mongoid/extensions/object/substitutable"
11
14
  require "mongoid/extensions/object/yoda"
@@ -19,6 +22,7 @@ require "mongoid/extensions/true_class/equality"
19
22
  require "mongoid/extensions/object_id/conversions"
20
23
 
21
24
  class Array #:nodoc
25
+ include Mongoid::Extensions::Array::DeepCopy
22
26
  include Mongoid::Extensions::Array::Deletion
23
27
  end
24
28
 
@@ -32,6 +36,7 @@ class FalseClass #:nodoc
32
36
  end
33
37
 
34
38
  class Hash #:nodoc
39
+ include Mongoid::Extensions::Hash::DeepCopy
35
40
  include Mongoid::Extensions::Hash::CriteriaHelpers
36
41
  include Mongoid::Extensions::Hash::Scoping
37
42
  end
@@ -46,6 +51,7 @@ end
46
51
 
47
52
  class Object #:nodoc:
48
53
  include Mongoid::Extensions::Object::Checks
54
+ include Mongoid::Extensions::Object::DeepCopy
49
55
  include Mongoid::Extensions::Object::Reflections
50
56
  include Mongoid::Extensions::Object::Substitutable
51
57
  include Mongoid::Extensions::Object::Yoda
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Extensions #:nodoc:
4
+ module Array #:nodoc:
5
+ module DeepCopy #:nodoc:
6
+
7
+ # Make a deep copy of the array.
8
+ #
9
+ # @example Make a deep copy.
10
+ # [ 1, 2, 3 ]._deep_copy
11
+ #
12
+ # @return [ Array ] The deep copy.
13
+ #
14
+ # @since 2.4.0
15
+ def _deep_copy
16
+ [].tap do |copy|
17
+ each do |value|
18
+ copy.push(value._deep_copy)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Extensions #:nodoc:
4
+ module Hash #:nodoc:
5
+ module DeepCopy #:nodoc:
6
+
7
+ # Make a deep copy of the hash.
8
+ #
9
+ # @example Make a deep copy.
10
+ # { :test => "value" }._deep_copy
11
+ #
12
+ # @return [ Hash ] The deep copy.
13
+ #
14
+ # @since 2.4.0
15
+ def _deep_copy
16
+ {}.tap do |copy|
17
+ each_pair do |key, value|
18
+ copy[key] = value._deep_copy
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -16,7 +16,7 @@ module Mongoid #:nodoc:
16
16
  # @return [ Hash ] The hash unmodified.
17
17
  #
18
18
  # @since 1.0.0
19
- def scoped(*args)
19
+ def as_conditions(*args)
20
20
  self
21
21
  end
22
22
  end
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Extensions #:nodoc:
4
+ module Object #:nodoc:
5
+ module DeepCopy #:nodoc:
6
+
7
+ # Make a deep copy of the object.
8
+ #
9
+ # @example Make a deep copy.
10
+ # "testing"._deep_copy
11
+ #
12
+ # @return [ Object ] The deep copy.
13
+ #
14
+ # @since 2.4.0
15
+ def _deep_copy
16
+ duplicable? ? dup : self
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -16,8 +16,8 @@ module Mongoid #:nodoc:
16
16
  # @return [ Object ] The result of the proc call.
17
17
  #
18
18
  # @since 1.0.0
19
- def scoped(*args)
20
- call(*args).scoped
19
+ def as_conditions(*args)
20
+ call(*args).as_conditions
21
21
  end
22
22
  end
23
23
  end
@@ -48,6 +48,7 @@ module Mongoid #:nodoc:
48
48
  "mod",
49
49
  "ne",
50
50
  "near",
51
+ "not",
51
52
  "nin",
52
53
  "size",
53
54
  "within",
@@ -1,30 +1,30 @@
1
1
  # encoding: utf-8
2
2
  require "mongoid/fields/mappings"
3
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/localized"
17
- require "mongoid/fields/serializable/nil_class"
18
- require "mongoid/fields/serializable/object"
19
- require "mongoid/fields/serializable/object_id"
20
- require "mongoid/fields/serializable/range"
21
- require "mongoid/fields/serializable/set"
22
- require "mongoid/fields/serializable/string"
23
- require "mongoid/fields/serializable/symbol"
24
- require "mongoid/fields/serializable/time"
25
- require "mongoid/fields/serializable/time_with_zone"
26
- require "mongoid/fields/serializable/foreign_keys/array"
27
- require "mongoid/fields/serializable/foreign_keys/object"
4
+ require "mongoid/fields/internal/timekeeping"
5
+ require "mongoid/fields/internal/array"
6
+ require "mongoid/fields/internal/big_decimal"
7
+ require "mongoid/fields/internal/binary"
8
+ require "mongoid/fields/internal/boolean"
9
+ require "mongoid/fields/internal/date"
10
+ require "mongoid/fields/internal/date_time"
11
+ require "mongoid/fields/internal/float"
12
+ require "mongoid/fields/internal/hash"
13
+ require "mongoid/fields/internal/integer"
14
+ require "mongoid/fields/internal/bignum"
15
+ require "mongoid/fields/internal/fixnum"
16
+ require "mongoid/fields/internal/localized"
17
+ require "mongoid/fields/internal/nil_class"
18
+ require "mongoid/fields/internal/object"
19
+ require "mongoid/fields/internal/object_id"
20
+ require "mongoid/fields/internal/range"
21
+ require "mongoid/fields/internal/set"
22
+ require "mongoid/fields/internal/string"
23
+ require "mongoid/fields/internal/symbol"
24
+ require "mongoid/fields/internal/time"
25
+ require "mongoid/fields/internal/time_with_zone"
26
+ require "mongoid/fields/internal/foreign_keys/array"
27
+ require "mongoid/fields/internal/foreign_keys/object"
28
28
 
29
29
  module Mongoid #:nodoc
30
30
 
@@ -33,6 +33,16 @@ module Mongoid #:nodoc
33
33
  extend ActiveSupport::Concern
34
34
 
35
35
  included do
36
+ class_attribute :aliased_fields
37
+ class_attribute :fields
38
+ class_attribute :non_proc_defaults
39
+ class_attribute :proc_defaults
40
+
41
+ self.aliased_fields = {}
42
+ self.fields = {}
43
+ self.non_proc_defaults = []
44
+ self.proc_defaults = []
45
+
36
46
  field(:_type, :type => String)
37
47
  field(:_id, :type => BSON::ObjectId)
38
48
 
@@ -40,28 +50,73 @@ module Mongoid #:nodoc
40
50
  alias :id= :_id=
41
51
  end
42
52
 
43
- # Get the default fields.
53
+ # Apply all default values to the document which are not procs.
44
54
  #
45
- # @note Refactored from using delegate for class load performance.
55
+ # @example Apply all the non-proc defaults.
56
+ # model.apply_non_proc_defaults
46
57
  #
47
- # @example Get the defaults.
48
- # model.defaults
58
+ # @return [ Array<String ] The names of the non-proc defaults.
49
59
  #
50
- # @return [ Array<String> ] The default field names.
51
- def defaults
52
- self.class.defaults
60
+ # @since 2.4.0
61
+ def apply_non_proc_defaults
62
+ non_proc_defaults.each do |name|
63
+ apply_default(name)
64
+ end
53
65
  end
54
66
 
55
- # Get the document's fields.
67
+ # Apply all default values to the document which are procs.
56
68
  #
57
- # @note Refactored from using delegate for class load performance.
69
+ # @example Apply all the proc defaults.
70
+ # model.apply_proc_defaults
58
71
  #
59
- # @example Get the fields.
60
- # model.fields
72
+ # @return [ Array<String ] The names of the proc defaults.
61
73
  #
62
- # @return [ Hash ] The fields.
63
- def fields
64
- self.class.fields
74
+ # @since 2.4.0
75
+ def apply_proc_defaults
76
+ proc_defaults.each do |name|
77
+ apply_default(name)
78
+ end
79
+ end
80
+
81
+ # Applies a single default value for the given name.
82
+ #
83
+ # @example Apply a single default.
84
+ # model.apply_default("name")
85
+ #
86
+ # @param [ String ] name The name of the field.
87
+ #
88
+ # @since 2.4.0
89
+ def apply_default(name)
90
+ unless attributes.has_key?(name)
91
+ if field = fields[name]
92
+ default = field.eval_default(self)
93
+ attribute_will_change!(name)
94
+ attributes[name] = default
95
+ end
96
+ end
97
+ end
98
+
99
+ # Apply all the defaults at once.
100
+ #
101
+ # @example Apply all the defaults.
102
+ # model.apply_defaults
103
+ #
104
+ # @since 2.4.0
105
+ def apply_defaults
106
+ apply_non_proc_defaults
107
+ apply_proc_defaults
108
+ end
109
+
110
+ # Get a list of all the default fields for the model.
111
+ #
112
+ # @example Get a list of the defaults.
113
+ # model.defaults
114
+ #
115
+ # @return [ Array<String ] The names of all defaults.
116
+ #
117
+ # @since 2.4.0
118
+ def defaults
119
+ self.class.defaults
65
120
  end
66
121
 
67
122
  class << self
@@ -103,26 +158,16 @@ module Mongoid #:nodoc
103
158
 
104
159
  module ClassMethods #:nodoc
105
160
 
106
- # Returns the default values for the fields on the document.
107
- #
108
- # @example Get the defaults.
109
- # Person.defaults
110
- #
111
- # @return [ Hash ] The field defaults.
112
- def defaults
113
- @defaults ||= []
114
- end
115
-
116
- # Set the defaults for the class.
161
+ # Get a list of all the default fields for the model.
117
162
  #
118
- # @example Set the defaults.
119
- # Person.defaults = defaults
163
+ # @example Get a list of the defaults.
164
+ # Model.defaults
120
165
  #
121
- # @param [ Array ] defaults The array of defaults to set.
166
+ # @return [ Array<String ] The names of all defaults.
122
167
  #
123
- # @since 2.0.0.rc.6
124
- def defaults=(defaults)
125
- @defaults = defaults
168
+ # @since 2.4.0
169
+ def defaults
170
+ non_proc_defaults + proc_defaults
126
171
  end
127
172
 
128
173
  # Defines all the fields that are accessible on the Document
@@ -141,32 +186,13 @@ module Mongoid #:nodoc
141
186
  #
142
187
  # @return [ Field ] The generated field
143
188
  def field(name, options = {})
189
+ named = name.to_s
144
190
  check_field_name!(name)
145
- add_field(name.to_s, options)
146
- end
147
-
148
- # Return the fields for this class.
149
- #
150
- # @example Get the fields.
151
- # Person.fields
152
- #
153
- # @return [ Hash ] The fields for this document.
154
- #
155
- # @since 2.0.0.rc.6
156
- def fields
157
- @fields ||= {}
158
- end
159
-
160
- # Set the fields for the class.
161
- #
162
- # @example Set the fields.
163
- # Person.fields = fields
164
- #
165
- # @param [ Hash ] fields The hash of fields to set.
166
- #
167
- # @since 2.0.0.rc.6
168
- def fields=(fields)
169
- @fields = fields
191
+ add_field(named, options).tap do
192
+ descendants.each do |subclass|
193
+ subclass.add_field(named, options)
194
+ end
195
+ end
170
196
  end
171
197
 
172
198
  # When inheriting, we want to copy the fields from the parent class and
@@ -181,7 +207,8 @@ module Mongoid #:nodoc
181
207
  # @since 2.0.0.rc.6
182
208
  def inherited(subclass)
183
209
  super
184
- subclass.defaults, subclass.fields = defaults.dup, fields.dup
210
+ subclass.fields, subclass.non_proc_defaults, subclass.proc_defaults =
211
+ fields.dup, non_proc_defaults.dup, proc_defaults.dup
185
212
  end
186
213
 
187
214
  # Is the field with the provided name a BSON::ObjectId?
@@ -219,6 +246,26 @@ module Mongoid #:nodoc
219
246
 
220
247
  protected
221
248
 
249
+ # Add the defaults to the model. This breaks them up between ones that
250
+ # are procs and ones that are not.
251
+ #
252
+ # @example Add to the defaults.
253
+ # Model.add_defaults(field)
254
+ #
255
+ # @param [ Field ] field The field to add for.
256
+ #
257
+ # @since 2.4.0
258
+ def add_defaults(field)
259
+ default, name = field.default_val, field.name.to_s
260
+ unless default.nil?
261
+ if field.default_val.is_a?(::Proc)
262
+ proc_defaults.push(name)
263
+ else
264
+ non_proc_defaults.push(name)
265
+ end
266
+ end
267
+ end
268
+
222
269
  # Define a field attribute for the +Document+.
223
270
  #
224
271
  # @example Set the field.
@@ -227,14 +274,16 @@ module Mongoid #:nodoc
227
274
  # @param [ Symbol ] name The name of the field.
228
275
  # @param [ Hash ] options The hash of options.
229
276
  def add_field(name, options = {})
230
- meth = options.delete(:as) || name
231
- type = options[:localize] ? Fields::Serializable::Localized : options[:type]
277
+ aliased = options[:as]
278
+ aliased_fields[aliased.to_s] = name if aliased
279
+ meth = aliased || name
280
+ type = options[:localize] ? Fields::Internal::Localized : options[:type]
232
281
  Mappings.for(type, options[:identity]).instantiate(name, options).tap do |field|
233
282
  fields[name] = field
234
- defaults << name unless field.default_val.nil?
283
+ add_defaults(field)
235
284
  create_accessors(name, meth, options)
236
285
  process_options(field)
237
- define_attribute_method(name)
286
+ create_dirty_methods(name)
238
287
  end
239
288
  end
240
289
 
@@ -290,28 +339,46 @@ module Mongoid #:nodoc
290
339
  # @param [ Hash ] options The options.
291
340
  def create_accessors(name, meth, options = {})
292
341
  field = fields[name]
293
- generated_field_methods.module_eval do
342
+ generated_methods.module_eval do
294
343
  if field.cast_on_read?
295
- define_method(meth) do
296
- field.deserialize(read_attribute(name))
297
- end
344
+ class_eval <<-EOM
345
+ def #{meth}
346
+ fields[#{name.inspect}].deserialize(read_attribute(#{name.inspect}))
347
+ end
348
+ EOM
298
349
  else
299
- define_method(meth) do
300
- read_attribute(name).tap do |value|
301
- if value.is_a?(Array) || value.is_a?(Hash)
302
- unless changed_attributes.include?(name)
303
- changed_attributes[name] = value.clone
350
+ class_eval <<-EOM
351
+ def #{meth}
352
+ read_attribute(#{name.inspect}).tap do |value|
353
+ if value.is_a?(Array) || value.is_a?(Hash)
354
+ attribute_will_change!(#{name.inspect})
304
355
  end
305
356
  end
306
357
  end
307
- end
358
+ EOM
308
359
  end
309
- define_method("#{meth}=") do |value|
310
- write_attribute(name, value)
311
- end
312
- define_method("#{meth}?") do
313
- attr = read_attribute(name)
314
- (options[:type] == Boolean) ? attr == true : attr.present?
360
+ class_eval <<-EOM
361
+ def #{meth}=(value)
362
+ write_attribute(#{name.inspect}, value)
363
+ end
364
+
365
+ def #{meth}?
366
+ attr = read_attribute(#{name.inspect})
367
+ attr == true || attr.present?
368
+ end
369
+ EOM
370
+
371
+ if options[:localize]
372
+ class_eval <<-EOM
373
+ def #{meth}_translations
374
+ attributes[#{name.inspect}]
375
+ end
376
+
377
+ def #{meth}_translations=(value)
378
+ attribute_will_change!(#{name.inspect})
379
+ attributes[#{name.inspect}] = value
380
+ end
381
+ EOM
315
382
  end
316
383
  end
317
384
  end
@@ -319,9 +386,9 @@ module Mongoid #:nodoc
319
386
  # Include the field methods as a module, so they can be overridden.
320
387
  #
321
388
  # @example Include the fields.
322
- # Person.generated_field_methods
323
- def generated_field_methods
324
- @generated_field_methods ||= begin
389
+ # Person.generated_methods
390
+ def generated_methods
391
+ @generated_methods ||= begin
325
392
  Module.new.tap do |mod|
326
393
  include mod
327
394
  end