From 12b42d89d20fbe0a7d811ebb7755e73ab6eac40a Mon Sep 17 00:00:00 2001 From: Durran Jordan Date: Wed, 3 Aug 2011 13:22:11 +0200 Subject: [PATCH] Many to many #clear no longer deletes documents: - This simply nullifies the relation to be consistent with AR behaviour. - For previous behaviour of #clear, please use #purge. - Fixes #988. --- lib/mongoid/relations/referenced/many.rb | 37 ++++++++++--------- .../relations/referenced/many_to_many.rb | 11 ++++-- .../relations/referenced/many_to_many_spec.rb | 6 +-- 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/lib/mongoid/relations/referenced/many.rb b/lib/mongoid/relations/referenced/many.rb index 6bc4ec8d3f..9b61ff116d 100644 --- a/lib/mongoid/relations/referenced/many.rb +++ b/lib/mongoid/relations/referenced/many.rb @@ -60,23 +60,6 @@ def build(attributes = {}, type = nil) end alias :new :build - # Clear the relation. Will delete the documents from the db if they are - # already persisted. - # - # @example Clear the relation. - # person.posts.clear - # - # @return [ Many ] The relation emptied. - # - # @since 2.0.0.beta.1 - def clear - criteria.delete_all - target.clear do |doc| - unbind_one(doc) - doc.destroyed = true - end - end - # Creates a new document on the references many relation. This will # save the document if the parent has been persisted. # @@ -259,6 +242,24 @@ def nullify end alias :nullify_all :nullify + # Clear the relation. Will delete the documents from the db if they are + # already persisted. + # + # @example Clear the relation. + # person.posts.clear + # + # @return [ Many ] The relation emptied. + # + # @since 2.0.0.beta.1 + def purge + criteria.delete_all + target.clear do |doc| + unbind_one(doc) + doc.destroyed = true + end + end + alias :clear :purge + # Substitutes the supplied target documents for the existing documents # in the relation. If the new target is nil, perform the necessary # deletion. @@ -273,7 +274,7 @@ def nullify # @since 2.0.0.rc.1 def substitute(replacement) tap do |proxy| - proxy.clear + proxy.purge proxy.push(replacement) if replacement end end diff --git a/lib/mongoid/relations/referenced/many_to_many.rb b/lib/mongoid/relations/referenced/many_to_many.rb index 5e13342721..78c80bc5f5 100644 --- a/lib/mongoid/relations/referenced/many_to_many.rb +++ b/lib/mongoid/relations/referenced/many_to_many.rb @@ -171,14 +171,19 @@ def initialize(base, target, metadata) # # @since 2.0.0.rc.1 def nullify - # @todo: Durran: This is wrong. - criteria.update(metadata.inverse_foreign_key => []) - # We need to update the inverse as well. + criteria.pull(metadata.inverse_foreign_key, base.id) + unless base.destroyed? + base.set( + metadata.foreign_key, + base.send(metadata.foreign_key).clear + ) + end target.clear do |doc| unbind_one(doc) end end alias :nullify_all :nullify + alias :clear :nullify private diff --git a/spec/functional/mongoid/relations/referenced/many_to_many_spec.rb b/spec/functional/mongoid/relations/referenced/many_to_many_spec.rb index 55b54188e5..acda530d30 100644 --- a/spec/functional/mongoid/relations/referenced/many_to_many_spec.rb +++ b/spec/functional/mongoid/relations/referenced/many_to_many_spec.rb @@ -705,11 +705,11 @@ preference.person_ids.should_not include(person.id) end - it "marks the documents as deleted" do - preference.should be_destroyed + it "does not delete the documents" do + preference.should_not be_destroyed end - it "deletes the documents from the db" do + it "persists the nullification" do person.reload.preferences.should be_empty end