Permalink
Browse files

[ WIP ] Delay removal to docs to post validation.

First part of solving #2367 although we still have broken other specs
now with the first part of the fix.
  • Loading branch information...
1 parent 57d3fa7 commit 0998e9097eae16c5b59014d958afa0ddff408f73 @durran durran committed Oct 21, 2012
View
@@ -24,6 +24,8 @@ matrix:
- rvm: jruby-head
jdk: openjdk7
env: JRUBY_OPTS="-Xcompile.invokedynamic=false"
-
+branches:
+ except:
+ - nested-destroy-validation-fail
services:
- mongodb
View
@@ -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|
@@ -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.
@@ -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
@@ -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?
@@ -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

0 comments on commit 0998e90

Please sign in to comment.