Skip to content

Commit

Permalink
Allow assignment of empty array to HABTM when no docs are loaded from…
Browse files Browse the repository at this point in the history
… the relation into memory. Fixes #1589.
  • Loading branch information
durran committed Jan 13, 2012
1 parent 32c250d commit f569af0
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 89 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ For instructions on upgrading to newer versions, visit

### Resolved Issues

* \#1589 Allow assignment of empty array to HABTM when no documents are yet
loaded into memory.

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

Expand Down
14 changes: 6 additions & 8 deletions lib/mongoid/relations/referenced/many.rb
Original file line number Diff line number Diff line change
Expand Up @@ -319,15 +319,13 @@ def purge
def substitute(replacement)
tap do |proxy|
if replacement
if replacement != proxy.in_memory
new_docs, docs = replacement.compact.uniq, []
new_ids = new_docs.map { |doc| doc.id }
remove_not_in(new_ids)
new_docs.each do |doc|
docs.push(doc) if doc.send(metadata.foreign_key) != base.id
end
proxy.concat(docs)
new_docs, docs = replacement.compact.uniq, []
new_ids = new_docs.map { |doc| doc.id }
remove_not_in(new_ids)
new_docs.each do |doc|
docs.push(doc) if doc.send(metadata.foreign_key) != base.id
end
proxy.concat(docs)
else
proxy.purge
end
Expand Down
6 changes: 2 additions & 4 deletions lib/mongoid/relations/referenced/many_to_many.rb
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,8 @@ def nullify
# @since 2.0.0.rc.1
def substitute(replacement)
tap do |proxy|
if replacement != proxy.in_memory
proxy.purge
proxy.push(replacement.compact.uniq) if replacement
end
proxy.purge
proxy.push(replacement.compact.uniq) unless replacement.blank?
end
end

Expand Down
158 changes: 81 additions & 77 deletions spec/functional/mongoid/relations/referenced/many_to_many_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -655,72 +655,40 @@
end
end

describe "#= nil" do
[ nil, [] ].each do |value|

context "when the relation is not polymorphic" do

context "when the inverse relation is not defined" do

let(:person) do
Person.new
end

let(:house) do
House.new
end

before do
person.houses << house
person.houses = nil
end
describe "#= #{value}" do

it "clears the relation" do
person.houses.should be_empty
end

it "clears the foreign keys" do
person.house_ids.should be_empty
end
end

context "when the parent is a new record" do

let(:person) do
Person.new
end
context "when the relation is not polymorphic" do

let(:preference) do
Preference.new
end
context "when the inverse relation is not defined" do

before do
person.preferences = [ preference ]
person.preferences = nil
end
let(:person) do
Person.new
end

it "sets the relation to an empty array" do
person.preferences.should be_empty
end
let(:house) do
House.new
end

it "removed the inverse relation" do
preference.people.should be_empty
end
before do
person.houses << house
person.houses = value
end

it "removes the foreign key values" do
person.preference_ids.should be_empty
end
it "clears the relation" do
person.houses.should be_empty
end

it "removes the inverse foreign key values" do
preference.person_ids.should be_empty
it "clears the foreign keys" do
person.house_ids.should be_empty
end
end
end

context "when the parent is not a new record" do

context "when the relation has been loaded" do
context "when the parent is a new record" do

let(:person) do
Person.create(:ssn => "437-11-1112")
Person.new
end

let(:preference) do
Expand All @@ -729,7 +697,7 @@

before do
person.preferences = [ preference ]
person.preferences = nil
person.preferences = value
end

it "sets the relation to an empty array" do
Expand All @@ -747,38 +715,74 @@
it "removes the inverse foreign key values" do
preference.person_ids.should be_empty
end

it "does not delete the target from the database" do
preference.should_not be_destroyed
end
end

context "when the relation has not been loaded" do
context "when the parent is not a new record" do

let(:preference) do
Preference.new
end
context "when the relation has been loaded" do

let(:person) do
Person.create(:ssn => "437-11-1112").tap do |p|
p.preferences = [ preference ]
let(:person) do
Person.create(:ssn => "437-11-1112")
end
end

let(:from_db) do
Person.find(person.id)
end
let(:preference) do
Preference.new
end

before do
from_db.preferences = nil
end
before do
person.preferences = [ preference ]
person.preferences = value
end

it "sets the relation to an empty array" do
from_db.preferences.should be_empty
it "sets the relation to an empty array" do
person.preferences.should be_empty
end

it "removed the inverse relation" do
preference.people.should be_empty
end

it "removes the foreign key values" do
person.preference_ids.should be_empty
end

it "removes the inverse foreign key values" do
preference.person_ids.should be_empty
end

it "does not delete the target from the database" do
preference.should_not be_destroyed
end
end

it "removes the foreign key values" do
from_db.preference_ids.should be_empty
context "when the relation has not been loaded" do

let(:preference) do
Preference.new
end

let(:person) do
Person.create(:ssn => "437-11-1112").tap do |p|
p.preferences = [ preference ]
end
end

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

before do
p "###############################"
from_db.preferences = value
end

it "sets the relation to an empty array" do
from_db.preferences.should be_empty
end

it "removes the foreign key values" do
from_db.preference_ids.should be_empty
end
end
end
end
Expand Down

0 comments on commit f569af0

Please sign in to comment.