diff --git a/lib/awesome_nested_set/model/prunable.rb b/lib/awesome_nested_set/model/prunable.rb index dc84cf0c..edefee4e 100644 --- a/lib/awesome_nested_set/model/prunable.rb +++ b/lib/awesome_nested_set/model/prunable.rb @@ -35,9 +35,14 @@ def destroy_descendants end end + # Use reverse to delete from deepest child to parent in order to respect any possible foreign keys + def decendants_to_destroy_in_order + descendants.reverse + end + def destroy_or_delete_descendants if acts_as_nested_set_options[:dependent] == :destroy - descendants.each do |model| + decendants_to_destroy_in_order.each do |model| model.skip_before_destroy = true model.destroy end diff --git a/spec/models/users_spec.rb b/spec/models/users_spec.rb index 4f6761d2..eaa7eb93 100644 --- a/spec/models/users_spec.rb +++ b/spec/models/users_spec.rb @@ -652,6 +652,19 @@ expect(User.valid?).to be_truthy end + it "destroys in the right order to respect foreign keys" do + User.acts_as_nested_set_options[:dependent] = :destroy + + expect(users(:top_level).decendants_to_destroy_in_order).to eq [ + users(:child_3), + users(:child_2_1), + users(:child_2), + users(:child_1) + ] + expect(users(:top_level)).to receive(:decendants_to_destroy_in_order).once.and_call_original + expect { users(:top_level).destroy! }.to change(User, :count).by(-5) + end + it "assigning_parent_uuid_on_create" do user = User.create!(:name => "Child", :parent_uuid => users(:child_2).uuid) expect(users(:child_2)).to eq(user.parent)