mongoid 2.3.5 → 2.4.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 (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