Skip to content

Commit

Permalink
Allow atomic set from explicit nil on array to new values. Fixes #1587
Browse files Browse the repository at this point in the history
  • Loading branch information
durran committed Jan 14, 2012
1 parent dc86d4e commit 714d92b
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 12 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ For instructions on upgrading to newer versions, visit
* \#1589 Allow assignment of empty array to HABTM when no documents are yet
loaded into memory.

* \#1587 When a previous value for an array field was an explicit nil, it can
now be reset atomically with new values.

* \#1585 `Model#respond_to?` returns true now for the setter when allowing
dynamic fields.

Expand Down
3 changes: 1 addition & 2 deletions lib/mongoid/dirty.rb
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,7 @@ def setters
field = fields[name]
key = embedded? ? "#{atomic_position}.#{name}" : name
if field && field.resizable?
pushes, pulls = (new || []) - (old || []), (old || []) - (new || [])
field.add_atomic_changes(self, key, modifications, pushes, pulls)
field.add_atomic_changes(self, key, modifications, new, old)
else
modifications[key] = new
end
Expand Down
14 changes: 9 additions & 5 deletions lib/mongoid/fields/internal/array.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,16 @@ class Array
#
# @since 2.4.0
def add_atomic_changes(document, key, mods, new, old)
if !new.empty? && !old.empty?
pushes = (new || []) - (old || [])
pulls = (old || []) - (new || [])
if old.nil?
mods[key] = pushes
elsif !pushes.empty? && !pulls.empty?
mods[key] = document.attributes[key]
elsif !new.empty?
document.atomic_array_pushes[key] = new
elsif !old.empty?
document.atomic_array_pulls[key] = old
elsif !pushes.empty?
document.atomic_array_pushes[key] = pushes
elsif !pulls.empty?
document.atomic_array_pulls[key] = pulls
end
end

Expand Down
14 changes: 9 additions & 5 deletions lib/mongoid/fields/internal/foreign_keys/array.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,16 @@ class Array
#
# @since 2.4.0
def add_atomic_changes(document, key, mods, new, old)
if new.any? && old.any?
pushes = (new || []) - (old || [])
pulls = (old || []) - (new || [])
if old.nil?
mods[key] = pushes
elsif !pushes.empty? && !pulls.empty?
mods[key] = document.attributes[key]
elsif new.any?
document.atomic_array_add_to_sets[key] = new
elsif old.any?
document.atomic_array_pulls[key] = old
elsif !pushes.empty?
document.atomic_array_add_to_sets[key] = pushes
elsif !pulls.empty?
document.atomic_array_pulls[key] = pulls
end
end

Expand Down
35 changes: 35 additions & 0 deletions spec/functional/mongoid/relations/embedded/one_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -643,4 +643,39 @@
end
end
end

context "when the embedded document has an array field" do

let!(:person) do
Person.create(:ssn => "673-11-2321")
end

let!(:name) do
person.create_name(
:first_name => "Syd",
:last_name => "Vicious",
:aliases => nil
)
end

context "when saving the array on a persisted document" do

let(:from_db) do
Person.find(person.id).name
end

before do
from_db.aliases = [ "Syd", "Sydney" ]
from_db.save
end

it "sets the values of the array" do
from_db.aliases.should eq([ "Syd", "Sydney" ])
end

it "persists the array" do
Person.find(person.id).name.aliases.should eq([ "Syd", "Sydney" ])
end
end
end
end

0 comments on commit 714d92b

Please sign in to comment.