Skip to content

Commit

Permalink
[ WIP ] Delay removal to docs to post validation.
Browse files Browse the repository at this point in the history
First part of solving #2367 although we still have broken other specs
now with the first part of the fix.
  • Loading branch information
durran committed Oct 24, 2012
1 parent 57d3fa7 commit 0998e90
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 3 deletions.
4 changes: 3 additions & 1 deletion .travis.yml
Expand Up @@ -24,6 +24,8 @@ matrix:
- rvm: jruby-head
jdk: openjdk7
env: JRUBY_OPTS="-Xcompile.invokedynamic=false"

branches:
except:
- nested-destroy-validation-fail
services:
- mongodb
14 changes: 14 additions & 0 deletions lib/mongoid/atomic.rb
Expand Up @@ -114,6 +114,7 @@ def atomic_array_add_to_sets
#
# @since 2.1.0
def atomic_updates
process_flagged_destroys
mods = Modifiers.new
generate_atomic_updates(mods, self)
_children.each do |child|
Expand Down Expand Up @@ -302,6 +303,19 @@ def flag_as_destroyed
atomic_path
end

def flagged_destroys
@flagged_destroys ||= []
end

def process_flagged_destroys
_assigning do
flagged_destroys.each do |block|
block.call
end
end
flagged_destroys.clear
end

private

# Get the atomic paths utility for this document.
Expand Down
1 change: 1 addition & 0 deletions lib/mongoid/persistence/modification.rb
Expand Up @@ -20,6 +20,7 @@ module Modification
# @since 2.1.0
def prepare(&block)
return false if validating? && document.invalid?(:update)
document.process_flagged_destroys
result = document.run_callbacks(:save) do
document.run_callbacks(:update) do
yield(document); true
Expand Down
7 changes: 5 additions & 2 deletions lib/mongoid/relations/builders/nested_attributes/many.rb
Expand Up @@ -103,8 +103,11 @@ def process_attributes(parent, attrs, options)
converted = first ? convert_id(first.class, id) : id
doc = existing.find(converted)
if destroyable?(attrs)
existing.delete(doc)
doc.destroy unless doc.embedded? || doc.destroyed?
doc.flagged_for_destroy = true
parent.flagged_destroys.push(->{
existing.delete(doc)
doc.destroy unless doc.embedded? || doc.destroyed?
})
else
attrs.delete_id
if metadata.embedded?
Expand Down
44 changes: 44 additions & 0 deletions spec/mongoid/nested_attributes_spec.rb
Expand Up @@ -1258,6 +1258,50 @@

context "when allow_destroy is true" do

context "when the parent validation failed" do

before(:all) do
Band.validates_presence_of :name
Band.accepts_nested_attributes_for :records, :allow_destroy => true
end

after(:all) do
Band.send(:undef_method, :records_attributes=)
Band.reset_callbacks(:validate)
end

let!(:band) do
Band.create(name: "Depeche Mode")
end

let!(:record) do
band.records.create
end

let(:attributes) do
{
name: nil,
records_attributes: { "foo" => { "id" => record.id, "_destroy" => true }}
}
end

before do
band.update_attributes(attributes)
end

it "does not remove the child document" do
band.records.should_not be_empty
end

it "keeps the child flagged for destruction" do
record.should be_flagged_for_destroy
end

it "does not persist any change" do
band.reload.records.should eq([ record ])
end
end

context "when the child accesses the parent after destroy" do

before(:all) do
Expand Down

0 comments on commit 0998e90

Please sign in to comment.