Permalink
Browse files

Fix multi-level hash update w/o nested attributes. Fixes #1936.

  • Loading branch information...
1 parent 8797e28 commit dec16ac7bb72b4aeadbe5ba9100a47dc835b3135 @durran durran committed May 5, 2012
View
@@ -7,6 +7,10 @@ For instructions on upgrading to newer versions, visit
### Resolved Issues
+* \#1936 Allow setting n levels deep embedded documents atomically without
+ conflicting mods when not using nested attributes or documents themselves
+ in an update call from the parent.
+
* \#1957/\#1954 Ensure database name is set with inheritance.
(Hans Hasselberg)
View
@@ -252,6 +252,9 @@ def delayed_atomic_pulls
# @example Get the atomic paths.
# document.atomic_paths
#
+ # @todo: Durran: Should probably raise error for embedded docs w/o
+ # metadata.
+ #
# @return [ Object ] The associated path.
#
# @since 2.1.0
@@ -307,7 +307,11 @@ def substitute(replacement)
atomically(:$set) do
base.delayed_atomic_sets.clear
if replacement.first.is_a?(Hash)
- replacement = Many.builder(base, metadata, replacement).build
+ replacement = replacement.map do |doc|
+ attributes = { metadata: metadata, _parent: base }
+ attributes.merge!(doc)
+ Factory.build(klass, attributes)
+ end
end
docs = replacement.compact
proxy.target = docs
@@ -319,6 +323,10 @@ def substitute(replacement)
end
if _assigning?
name = _unscoped.first.atomic_path
+ base._children.each do |child|
+ child.delayed_atomic_sets.clear
+ end
+ base.instance_variable_set(:@_children, nil)
base.delayed_atomic_sets[name] = proxy.as_document
end
end
@@ -3025,4 +3025,53 @@
end
end
end
+
+ context "when adding a document" do
+
+ let(:person) do
+ Person.new
+ end
+
+ let(:address_one) do
+ Address.new(street: "hobrecht")
+ end
+
+ let(:first_add) do
+ person.addresses.push(address_one)
+ end
+ end
+
+ context "when updating multiple levels in one update" do
+
+ let!(:person) do
+ Person.create(
+ addresses: [
+ { locations: [{ name: "home" }]}
+ ]
+ )
+ end
+
+ context "when updating with hashes" do
+
+ let(:from_db) do
+ Person.find(person.id)
+ end
+
+ before do
+ from_db.update_attributes(
+ addresses: [
+ { locations: [{ name: "work" }]}
+ ]
+ )
+ end
+
+ let(:updated) do
+ person.reload.addresses.first.locations.first
+ end
+
+ it "updates the nested document" do
+ updated.name.should eq("work")
+ end
+ end
+ end
end

0 comments on commit dec16ac

Please sign in to comment.