From 8a282c9ac096fa1fb1fb5ee638524db3cd2a5d5b Mon Sep 17 00:00:00 2001 From: John Nunemaker Date: Sun, 26 Dec 2010 23:10:15 -0500 Subject: [PATCH] Fixed issue with nested embedded one's not getting _id set properly. Test thanks to bhbryant. --- .../associations/one_embedded_proxy.rb | 1 + lib/mongo_mapper/plugins/clone.rb | 2 +- lib/mongo_mapper/plugins/keys.rb | 16 +++++++------- .../associations/test_one_embedded_proxy.rb | 21 ++++++++++++++++++- 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb b/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb index a6e9b6a5c..5dc983ea2 100644 --- a/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb +++ b/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb @@ -16,6 +16,7 @@ def replace(doc) else @target = klass.load(doc) end + @target.default_id_value if @target && @target.id.nil? assign_references(@target) loaded @target diff --git a/lib/mongo_mapper/plugins/clone.rb b/lib/mongo_mapper/plugins/clone.rb index 8b2a20463..11443c246 100644 --- a/lib/mongo_mapper/plugins/clone.rb +++ b/lib/mongo_mapper/plugins/clone.rb @@ -6,7 +6,7 @@ module InstanceMethods def initialize_copy(other) @_new = true @_destroyed = false - default_id_value({}) + default_id_value associations.each do |name, association| instance_variable_set(association.ivar, nil) end diff --git a/lib/mongo_mapper/plugins/keys.rb b/lib/mongo_mapper/plugins/keys.rb index cce291b80..cb42c63a4 100644 --- a/lib/mongo_mapper/plugins/keys.rb +++ b/lib/mongo_mapper/plugins/keys.rb @@ -258,6 +258,13 @@ def embedded_keys keys.values.select { |key| key.embeddable? } end + def default_id_value(attrs={}) + id_provided = !attrs.nil? && attrs.keys.map { |k| k.to_s }.detect { |k| k == 'id' || k == '_id' } + if !id_provided && self.class.can_default_id? + write_key :_id, BSON::ObjectId.new + end + end + private def load_from_database(attrs) return if attrs.blank? @@ -270,15 +277,6 @@ def load_from_database(attrs) end end - def default_id_value(attrs) - unless attrs.nil? - id_provided = attrs.keys.map { |k| k.to_s }.detect { |k| k == 'id' || k == '_id' } - if !id_provided && self.class.can_default_id? - write_key :_id, BSON::ObjectId.new - end - end - end - def ensure_key_exists(name) self.class.key(name) unless respond_to?("#{name}=") end diff --git a/test/functional/associations/test_one_embedded_proxy.rb b/test/functional/associations/test_one_embedded_proxy.rb index 87afd0447..762c0b1e4 100644 --- a/test/functional/associations/test_one_embedded_proxy.rb +++ b/test/functional/associations/test_one_embedded_proxy.rb @@ -48,7 +48,7 @@ def setup should "not have problem loading root document if embedded one is nil" do @post_class.one :author, :class => @author_class post = @post_class.create - + lambda { @post_class.find(post.id) }.should_not raise_error @@ -78,4 +78,23 @@ def setup post.author?.should be_true end + should "initialize id for nested embedded document created from hash" do + @address_class = EDoc('Address') do + key :city, String + key :state, String + end + @author_class.one(:address, :class => @address_class) + @post_class.one(:author, :class => @author_class) + + post = @post_class.create(:title => 'Post Title', :author => { + :name => 'Frank', + :address => { + :city => 'Boston', + :state => 'MA' + } + }) + + post.author.address.id.should_not be_nil + end + end