mongo_mapper-unstable 2010.1.6 → 2010.1.12

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 (86) hide show
  1. data/VERSION +1 -1
  2. data/lib/mongo_mapper/descendant_appends.rb +44 -0
  3. data/lib/mongo_mapper/document.rb +54 -98
  4. data/lib/mongo_mapper/embedded_document.rb +28 -348
  5. data/lib/mongo_mapper/finder_options.rb +15 -33
  6. data/lib/mongo_mapper/plugins/associations/base.rb +121 -0
  7. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +28 -0
  8. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +23 -0
  9. data/lib/mongo_mapper/plugins/associations/collection.rb +21 -0
  10. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +49 -0
  11. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +139 -0
  12. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
  13. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +117 -0
  14. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +31 -0
  15. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +23 -0
  16. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +13 -0
  17. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +66 -0
  18. data/lib/mongo_mapper/plugins/associations/proxy.rb +118 -0
  19. data/lib/mongo_mapper/plugins/associations.rb +104 -0
  20. data/lib/mongo_mapper/plugins/callbacks.rb +65 -0
  21. data/lib/mongo_mapper/plugins/clone.rb +13 -0
  22. data/lib/mongo_mapper/plugins/descendants.rb +16 -0
  23. data/lib/mongo_mapper/plugins/dirty.rb +119 -0
  24. data/lib/mongo_mapper/plugins/equality.rb +11 -0
  25. data/lib/mongo_mapper/plugins/identity_map.rb +66 -0
  26. data/lib/mongo_mapper/plugins/inspect.rb +14 -0
  27. data/lib/mongo_mapper/plugins/keys.rb +295 -0
  28. data/lib/mongo_mapper/plugins/logger.rb +17 -0
  29. data/lib/mongo_mapper/plugins/pagination.rb +85 -0
  30. data/lib/mongo_mapper/plugins/rails.rb +45 -0
  31. data/lib/mongo_mapper/plugins/serialization.rb +109 -0
  32. data/lib/mongo_mapper/plugins/validations.rb +48 -0
  33. data/lib/mongo_mapper/plugins.rb +19 -0
  34. data/lib/mongo_mapper/support.rb +36 -15
  35. data/lib/mongo_mapper.rb +23 -22
  36. data/performance/read_write.rb +52 -0
  37. data/specs.watchr +23 -2
  38. data/test/functional/associations/test_belongs_to_proxy.rb +1 -1
  39. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +58 -39
  40. data/test/functional/associations/test_many_embedded_proxy.rb +103 -69
  41. data/test/functional/test_dirty.rb +1 -1
  42. data/test/functional/test_document.rb +25 -25
  43. data/test/functional/test_embedded_document.rb +66 -63
  44. data/test/functional/test_identity_map.rb +233 -0
  45. data/test/functional/test_modifiers.rb +14 -0
  46. data/test/functional/test_string_id_compatibility.rb +4 -4
  47. data/test/functional/test_validations.rb +13 -0
  48. data/test/models.rb +0 -39
  49. data/test/test_helper.rb +8 -2
  50. data/test/unit/associations/test_base.rb +1 -1
  51. data/test/unit/associations/test_proxy.rb +3 -3
  52. data/test/unit/test_descendant_appends.rb +71 -0
  53. data/test/unit/test_document.rb +35 -46
  54. data/test/unit/test_embedded_document.rb +218 -271
  55. data/test/unit/{test_key.rb → test_keys.rb} +0 -0
  56. data/test/unit/test_pagination.rb +10 -2
  57. data/test/unit/test_plugins.rb +42 -0
  58. data/test/unit/test_rails.rb +123 -0
  59. data/test/unit/{test_serializations.rb → test_serialization.rb} +0 -0
  60. data/test/unit/test_support.rb +10 -6
  61. data/test/unit/test_time_zones.rb +2 -2
  62. metadata +44 -31
  63. data/lib/mongo_mapper/associations/base.rb +0 -119
  64. data/lib/mongo_mapper/associations/belongs_to_polymorphic_proxy.rb +0 -26
  65. data/lib/mongo_mapper/associations/belongs_to_proxy.rb +0 -21
  66. data/lib/mongo_mapper/associations/collection.rb +0 -19
  67. data/lib/mongo_mapper/associations/in_array_proxy.rb +0 -137
  68. data/lib/mongo_mapper/associations/many_documents_as_proxy.rb +0 -26
  69. data/lib/mongo_mapper/associations/many_documents_proxy.rb +0 -115
  70. data/lib/mongo_mapper/associations/many_embedded_polymorphic_proxy.rb +0 -31
  71. data/lib/mongo_mapper/associations/many_embedded_proxy.rb +0 -54
  72. data/lib/mongo_mapper/associations/many_polymorphic_proxy.rb +0 -11
  73. data/lib/mongo_mapper/associations/one_proxy.rb +0 -64
  74. data/lib/mongo_mapper/associations/proxy.rb +0 -116
  75. data/lib/mongo_mapper/associations.rb +0 -78
  76. data/lib/mongo_mapper/callbacks.rb +0 -61
  77. data/lib/mongo_mapper/dirty.rb +0 -117
  78. data/lib/mongo_mapper/key.rb +0 -36
  79. data/lib/mongo_mapper/mongo_mapper.rb +0 -125
  80. data/lib/mongo_mapper/pagination.rb +0 -66
  81. data/lib/mongo_mapper/rails_compatibility/document.rb +0 -15
  82. data/lib/mongo_mapper/rails_compatibility/embedded_document.rb +0 -28
  83. data/lib/mongo_mapper/serialization.rb +0 -54
  84. data/lib/mongo_mapper/serializers/json_serializer.rb +0 -48
  85. data/lib/mongo_mapper/validations.rb +0 -39
  86. data/test/functional/test_rails_compatibility.rb +0 -25
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2010.01.06
1
+ 2010.01.12
@@ -0,0 +1,44 @@
1
+ module MongoMapper
2
+ module DescendantAppends
3
+ def included(model)
4
+ extra_extensions.each { |extension| model.extend(extension) }
5
+ extra_inclusions.each { |inclusion| model.send(:include, inclusion) }
6
+ descendants << model
7
+ end
8
+
9
+ # @api public
10
+ def descendants
11
+ @descendants ||= Set.new
12
+ end
13
+
14
+ # @api public
15
+ def append_extensions(*extensions)
16
+ extra_extensions.concat extensions
17
+
18
+ # Add the extension to existing descendants
19
+ descendants.each do |model|
20
+ extensions.each { |extension| model.extend(extension) }
21
+ end
22
+ end
23
+
24
+ # @api public
25
+ def append_inclusions(*inclusions)
26
+ extra_inclusions.concat inclusions
27
+
28
+ # Add the inclusion to existing descendants
29
+ descendants.each do |model|
30
+ inclusions.each { |inclusion| model.send(:include, inclusion) }
31
+ end
32
+ end
33
+
34
+ # @api private
35
+ def extra_extensions
36
+ @extra_extensions ||= []
37
+ end
38
+
39
+ # @api private
40
+ def extra_inclusions
41
+ @extra_inclusions ||= []
42
+ end
43
+ end
44
+ end
@@ -1,66 +1,38 @@
1
- require 'set'
2
-
3
1
  module MongoMapper
4
2
  module Document
3
+ extend DescendantAppends
4
+
5
5
  def self.included(model)
6
6
  model.class_eval do
7
- include EmbeddedDocument
8
7
  include InstanceMethods
9
- include Callbacks
10
- include Dirty
11
- include RailsCompatibility::Document
12
- extend Validations::Macros
13
- extend ClassMethods
14
- extend Finders
15
-
16
- def self.per_page
17
- 25
18
- end unless respond_to?(:per_page)
19
- end
20
-
21
- extra_extensions.each { |extension| model.extend(extension) }
22
- extra_inclusions.each { |inclusion| model.send(:include, inclusion) }
23
-
24
- descendants << model
25
- end
26
-
27
- def self.descendants
28
- @descendants ||= Set.new
29
- end
30
-
31
- def self.append_extensions(*extensions)
32
- extra_extensions.concat extensions
33
-
34
- # Add the extension to existing descendants
35
- descendants.each do |model|
36
- extensions.each { |extension| model.extend(extension) }
8
+ extend ClassMethods
9
+ extend Finders
10
+
11
+ extend Plugins
12
+ plugin Plugins::Associations
13
+ plugin Plugins::Clone
14
+ plugin Plugins::Descendants
15
+ plugin Plugins::Equality
16
+ plugin Plugins::Inspect
17
+ plugin Plugins::Keys
18
+ plugin Plugins::Dirty # for now dirty needs to be after keys
19
+ plugin Plugins::Logger
20
+ plugin Plugins::Pagination
21
+ plugin Plugins::Rails
22
+ plugin Plugins::Serialization
23
+ plugin Plugins::Validations
24
+ plugin Plugins::Callbacks # for now callbacks needs to be after validations
25
+
26
+ extend Plugins::Validations::DocumentMacros
37
27
  end
38
- end
39
-
40
- # @api private
41
- def self.extra_extensions
42
- @extra_extensions ||= []
43
- end
44
-
45
- def self.append_inclusions(*inclusions)
46
- extra_inclusions.concat inclusions
47
-
48
- # Add the inclusion to existing descendants
49
- descendants.each do |model|
50
- inclusions.each { |inclusion| model.send :include, inclusion }
51
- end
52
- end
53
-
54
- # @api private
55
- def self.extra_inclusions
56
- @extra_inclusions ||= []
28
+
29
+ super
57
30
  end
58
31
 
59
32
  module ClassMethods
60
- def key(*args)
61
- key = super
62
- create_indexes_for(key)
63
- key
33
+ def inherited(subclass)
34
+ subclass.set_collection_name(collection_name)
35
+ super
64
36
  end
65
37
 
66
38
  def ensure_index(name_or_array, options={})
@@ -98,17 +70,6 @@ module MongoMapper
98
70
  nil
99
71
  end
100
72
 
101
- def paginate(options)
102
- per_page = options.delete(:per_page) || self.per_page
103
- page = options.delete(:page)
104
- total_entries = count(options)
105
- pagination = Pagination::PaginationProxy.new(total_entries, page, per_page)
106
-
107
- options.merge!(:limit => pagination.limit, :skip => pagination.skip)
108
- pagination.subject = find_every(options)
109
- pagination
110
- end
111
-
112
73
  def first(options={})
113
74
  find_one(options)
114
75
  end
@@ -204,6 +165,10 @@ module MongoMapper
204
165
  modifier_update('$pullAll', args)
205
166
  end
206
167
 
168
+ def pop(*args)
169
+ modifier_update('$pop', args)
170
+ end
171
+
207
172
  def modifier_update(modifier, args)
208
173
  criteria, keys = criteria_and_keys_from_args(args)
209
174
  modifiers = {modifier => keys}
@@ -218,6 +183,10 @@ module MongoMapper
218
183
  end
219
184
  private :criteria_and_keys_from_args
220
185
 
186
+ def embeddable?
187
+ false
188
+ end
189
+
221
190
  def connection(mongo_connection=nil)
222
191
  if mongo_connection.nil?
223
192
  @connection ||= MongoMapper.connection
@@ -269,23 +238,19 @@ module MongoMapper
269
238
  end
270
239
 
271
240
  def single_collection_inherited?
272
- keys.has_key?('_type') && single_collection_inherited_superclass?
241
+ keys.key?(:_type) && single_collection_inherited_superclass?
273
242
  end
274
243
 
275
244
  def single_collection_inherited_superclass?
276
- superclass.respond_to?(:keys) && superclass.keys.has_key?('_type')
245
+ superclass.respond_to?(:keys) && superclass.keys.key?(:_type)
277
246
  end
278
247
 
279
248
  private
280
- def create_indexes_for(key)
281
- ensure_index key.name if key.options[:index]
282
- end
283
-
284
249
  def initialize_each(*docs)
285
250
  instances = []
286
251
  docs = [{}] if docs.blank?
287
252
  docs.flatten.each do |attrs|
288
- doc = initialize_doc(attrs)
253
+ doc = new(attrs)
289
254
  yield(doc)
290
255
  instances << doc
291
256
  end
@@ -295,7 +260,7 @@ module MongoMapper
295
260
  def find_every(options)
296
261
  criteria, options = to_finder_options(options)
297
262
  collection.find(criteria, options).to_a.map do |doc|
298
- initialize_doc(doc)
263
+ load(doc)
299
264
  end
300
265
  end
301
266
 
@@ -313,7 +278,7 @@ module MongoMapper
313
278
  def find_one(options={})
314
279
  criteria, options = to_finder_options(options)
315
280
  if doc = collection.find_one(criteria, options)
316
- initialize_doc(doc)
281
+ load(doc)
317
282
  end
318
283
  end
319
284
 
@@ -366,20 +331,12 @@ module MongoMapper
366
331
  def collection
367
332
  self.class.collection
368
333
  end
369
-
334
+
370
335
  def database
371
336
  self.class.database
372
337
  end
373
338
 
374
- def new?
375
- read_attribute('_id').blank? || using_custom_id?
376
- end
377
-
378
339
  def save(options={})
379
- if options === false
380
- ActiveSupport::Deprecation.warn "save with true/false is deprecated. You should now use :validate => true/false."
381
- options = {:validate => false}
382
- end
383
340
  options.reverse_merge!(:validate => true)
384
341
  perform_validations = options.delete(:validate)
385
342
  !perform_validations || valid? ? create_or_update(options) : false
@@ -388,9 +345,19 @@ module MongoMapper
388
345
  def save!
389
346
  save || raise(DocumentNotValid.new(self))
390
347
  end
348
+
349
+ def update_attributes(attrs={})
350
+ self.attributes = attrs
351
+ save
352
+ end
353
+
354
+ def update_attributes!(attrs={})
355
+ self.attributes = attrs
356
+ save!
357
+ end
391
358
 
392
359
  def destroy
393
- self.class.delete(id) unless new?
360
+ delete
394
361
  end
395
362
 
396
363
  def delete
@@ -411,34 +378,23 @@ module MongoMapper
411
378
  end
412
379
 
413
380
  def create(options={})
414
- assign_id
415
381
  save_to_collection(options)
416
382
  end
417
383
 
418
- def assign_id
419
- if read_attribute(:_id).blank?
420
- write_attribute :_id, Mongo::ObjectID.new
421
- end
422
- end
423
-
424
384
  def update(options={})
425
385
  save_to_collection(options)
426
386
  end
427
387
 
428
388
  def save_to_collection(options={})
429
- clear_custom_id_flag
430
389
  safe = options.delete(:safe) || false
390
+ @new = false
431
391
  collection.save(to_mongo, :safe => safe)
432
392
  end
433
393
 
434
394
  def update_timestamps
435
395
  now = Time.now.utc
436
- write_attribute('created_at', now) if new? && read_attribute('created_at').blank?
437
- write_attribute('updated_at', now)
438
- end
439
-
440
- def clear_custom_id_flag
441
- @using_custom_id = nil
396
+ self[:created_at] = now if new? && !created_at?
397
+ self[:updated_at] = now
442
398
  end
443
399
  end
444
400
  end # Document
@@ -1,380 +1,60 @@
1
1
  module MongoMapper
2
2
  module EmbeddedDocument
3
+ extend DescendantAppends
4
+
3
5
  def self.included(model)
4
6
  model.class_eval do
5
- extend ClassMethods
6
7
  include InstanceMethods
7
-
8
- extend Associations::ClassMethods
9
- include Associations::InstanceMethods
10
-
11
- include RailsCompatibility::EmbeddedDocument
12
- include Validatable
13
- include Serialization
8
+ extend ClassMethods
9
+
10
+ extend Plugins
11
+ plugin Plugins::Associations
12
+ plugin Plugins::Clone
13
+ plugin Plugins::Descendants
14
+ plugin Plugins::Equality
15
+ plugin Plugins::Inspect
16
+ plugin Plugins::Keys
17
+ plugin Plugins::Logger
18
+ plugin Plugins::Rails
19
+ plugin Plugins::Serialization
20
+ plugin Plugins::Validations
14
21
 
15
- extend Validations::Macros
16
-
17
- key :_id, ObjectId
18
22
  attr_accessor :_root_document
19
23
  end
24
+
25
+ super
20
26
  end
21
27
 
22
28
  module ClassMethods
23
- def logger
24
- MongoMapper.logger
25
- end
26
-
27
- def inherited(subclass)
28
- unless subclass.embeddable?
29
- subclass.set_collection_name(collection_name)
30
- end
31
-
32
- (@subclasses ||= []) << subclass
33
- end
34
-
35
- def subclasses
36
- @subclasses
37
- end
38
-
39
- def keys
40
- @keys ||= if parent = parent_model
41
- parent.keys.dup
42
- else
43
- HashWithIndifferentAccess.new
44
- end
45
- end
46
-
47
- def key(*args)
48
- key = Key.new(*args)
49
- keys[key.name] = key
50
-
51
- create_accessors_for(key)
52
- create_key_in_subclasses(*args)
53
- create_validations_for(key)
54
-
55
- key
56
- end
57
-
58
- def using_object_id?
59
- object_id_key?(:_id)
60
- end
61
-
62
- def object_id_key?(name)
63
- key = keys[name.to_s]
64
- key && key.type == ObjectId
65
- end
66
-
67
29
  def embeddable?
68
- !self.ancestors.include?(Document)
69
- end
70
-
71
- def parent_model
72
- (ancestors - [self,EmbeddedDocument]).find do |parent_class|
73
- parent_class.ancestors.include?(EmbeddedDocument)
74
- end
75
- end
76
-
77
- def to_mongo(instance)
78
- return nil if instance.nil?
79
- instance.to_mongo
80
- end
81
-
82
- def from_mongo(value)
83
- return nil if value.nil?
84
- value.is_a?(self) ? value : initialize_doc(value)
85
- end
86
-
87
- private
88
- def initialize_doc(doc)
89
- begin
90
- klass = doc['_type'].present? ? doc['_type'].constantize : self
91
- klass.new(doc)
92
- rescue NameError
93
- new(doc)
94
- end
95
- end
96
-
97
- def accessors_module
98
- module_defined = if method(:const_defined?).arity == 1 # Ruby 1.9 compat check
99
- const_defined?('MongoMapperKeys')
100
- else
101
- const_defined?('MongoMapperKeys', false)
102
- end
103
-
104
- if module_defined
105
- const_get 'MongoMapperKeys'
106
- else
107
- const_set 'MongoMapperKeys', Module.new
108
- end
109
- end
110
-
111
- def create_accessors_for(key)
112
- accessors_module.module_eval <<-end_eval
113
- def #{key.name}
114
- read_attribute(:'#{key.name}')
115
- end
116
-
117
- def #{key.name}_before_typecast
118
- read_attribute_before_typecast(:'#{key.name}')
119
- end
120
-
121
- def #{key.name}=(value)
122
- write_attribute(:'#{key.name}', value)
123
- end
124
-
125
- def #{key.name}?
126
- read_attribute(:#{key.name}).present?
127
- end
128
- end_eval
129
- include accessors_module
130
- end
131
-
132
- def create_key_in_subclasses(*args)
133
- return if subclasses.blank?
134
-
135
- subclasses.each do |subclass|
136
- subclass.key(*args)
137
- end
138
- end
139
-
140
- def create_validations_for(key)
141
- attribute = key.name.to_sym
142
-
143
- if key.options[:required]
144
- validates_presence_of(attribute)
145
- end
146
-
147
- if key.options[:unique]
148
- validates_uniqueness_of(attribute)
149
- end
150
-
151
- if key.options[:numeric]
152
- number_options = key.type == Integer ? {:only_integer => true} : {}
153
- validates_numericality_of(attribute, number_options)
154
- end
155
-
156
- if key.options[:format]
157
- validates_format_of(attribute, :with => key.options[:format])
158
- end
159
-
160
- if key.options[:length]
161
- length_options = case key.options[:length]
162
- when Integer
163
- {:minimum => 0, :maximum => key.options[:length]}
164
- when Range
165
- {:within => key.options[:length]}
166
- when Hash
167
- key.options[:length]
168
- end
169
- validates_length_of(attribute, length_options)
170
- end
30
+ true
171
31
  end
172
32
  end
173
33
 
174
34
  module InstanceMethods
175
- def initialize(attrs={})
176
- unless attrs.nil?
177
- associations.each do |name, association|
178
- if collection = attrs.delete(name)
179
- if association.many? && association.klass.embeddable?
180
- root_document = attrs[:_root_document] || self
181
- collection.each do |doc|
182
- doc[:_root_document] = root_document
183
- end
184
- end
185
- send("#{association.name}=", collection)
186
- end
187
- end
188
-
189
- self.attributes = attrs
190
-
191
- if respond_to?(:_type=) && self['_type'].blank?
192
- self._type = self.class.name
193
- end
194
- end
195
-
196
- if self.class.embeddable?
197
- if read_attribute(:_id).blank?
198
- write_attribute :_id, Mongo::ObjectID.new
199
- @new_document = true
200
- else
201
- @new_document = false
202
- end
203
- end
204
- end
205
-
206
- def new?
207
- !!@new_document
208
- end
209
-
210
- def to_param
211
- id.to_s
212
- end
213
-
214
- def attributes=(attrs)
215
- return if attrs.blank?
216
- attrs.each_pair do |name, value|
217
- writer_method = "#{name}="
218
-
219
- if respond_to?(writer_method)
220
- self.send(writer_method, value)
221
- else
222
- self[name.to_s] = value
223
- end
224
- end
225
- end
226
-
227
- def attributes
228
- attrs = HashWithIndifferentAccess.new
229
-
230
- embedded_keys.each do |key|
231
- attrs[key.name] = read_attribute(key.name).try(:attributes)
232
- end
233
-
234
- non_embedded_keys.each do |key|
235
- attrs[key.name] = read_attribute(key.name)
236
- end
237
-
238
- embedded_associations.each do |association|
239
- documents = instance_variable_get(association.ivar)
240
- next if documents.nil?
241
- attrs[association.name] = documents.collect { |doc| doc.attributes }
242
- end
243
-
244
- attrs
245
- end
246
-
247
- def to_mongo
248
- attrs = HashWithIndifferentAccess.new
249
-
250
- _keys.each_pair do |name, key|
251
- value = key.set(read_attribute(key.name))
252
- attrs[name] = value unless value.nil?
253
- end
254
-
255
- embedded_associations.each do |association|
256
- if documents = instance_variable_get(association.ivar)
257
- attrs[association.name] = documents.map { |document| document.to_mongo }
258
- end
259
- end
260
-
261
- attrs
262
- end
263
-
264
- def clone
265
- clone_attributes = self.attributes
266
- clone_attributes.delete("_id")
267
- self.class.new(clone_attributes)
268
- end
269
-
270
- def [](name)
271
- read_attribute(name)
272
- end
273
-
274
- def []=(name, value)
275
- ensure_key_exists(name)
276
- write_attribute(name, value)
277
- end
278
-
279
- def ==(other)
280
- other.is_a?(self.class) && _id == other._id
281
- end
282
-
283
- def id
284
- self[:_id]
285
- end
286
-
287
- def id=(value)
288
- if self.class.using_object_id?
289
- value = MongoMapper.normalize_object_id(value)
290
- else
291
- @using_custom_id = true
292
- end
293
-
294
- self[:_id] = value
295
- end
296
-
297
- def using_custom_id?
298
- !!@using_custom_id
299
- end
300
-
301
- def inspect
302
- attributes_as_nice_string = key_names.collect do |name|
303
- "#{name}: #{read_attribute(name).inspect}"
304
- end.join(", ")
305
- "#<#{self.class} #{attributes_as_nice_string}>"
306
- end
307
-
308
35
  def save(options={})
309
- _root_document.try(:save, options)
36
+ if result = _root_document.try(:save, options)
37
+ @new = false
38
+ end
39
+ result
310
40
  end
311
41
 
312
42
  def save!(options={})
313
- _root_document.try(:save!, options)
43
+ if result = _root_document.try(:save!, options)
44
+ @new = false
45
+ end
46
+ result
314
47
  end
315
48
 
316
49
  def update_attributes(attrs={})
317
50
  self.attributes = attrs
318
- save
51
+ self.save
319
52
  end
320
53
 
321
54
  def update_attributes!(attrs={})
322
55
  self.attributes = attrs
323
- save!
56
+ self.save!
324
57
  end
325
-
326
- def logger
327
- self.class.logger
328
- end
329
-
330
- private
331
- def _keys
332
- self.metaclass.keys
333
- end
334
-
335
- def key_names
336
- _keys.keys
337
- end
338
-
339
- def non_embedded_keys
340
- _keys.values.select { |key| !key.embeddable? }
341
- end
342
-
343
- def embedded_keys
344
- _keys.values.select { |key| key.embeddable? }
345
- end
346
-
347
- def ensure_key_exists(name)
348
- self.metaclass.key(name) unless respond_to?("#{name}=")
349
- end
350
-
351
- def read_attribute(name)
352
- if key = _keys[name]
353
- value = key.get(instance_variable_get("@#{name}"))
354
- instance_variable_set "@#{name}", value
355
- value
356
- else
357
- raise KeyNotFound, "Could not find key: #{name.inspect}"
358
- end
359
- end
360
-
361
- def read_attribute_before_typecast(name)
362
- instance_variable_get("@#{name}_before_typecast")
363
- end
364
-
365
- def write_attribute(name, value)
366
- key = _keys[name]
367
- instance_variable_set "@#{name}_before_typecast", value
368
- instance_variable_set "@#{name}", key.set(value)
369
- end
370
-
371
- def embedded_associations
372
- associations.select do |name, association|
373
- association.embeddable?
374
- end.map do |name, association|
375
- association
376
- end
377
- end
378
58
  end # InstanceMethods
379
59
  end # EmbeddedDocument
380
60
  end # MongoMapper