mongo_mapper-unstable 2010.1.6 → 2010.1.12

Sign up to get free protection for your applications and to get access to all the features.
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