Permalink
Browse files

Fix for "Save callbacks fire once for every outging has_one node" clo…

…ses #172

The write performance will probably be increase since the size of the call stack has been decrease a lot since we are avoiding saving nodes twice.
This might also be a solution for issue #166
  • Loading branch information...
1 parent 0724e56 commit ec6401924e14cb4f06c7495ab2bcfbed3cdf2407 @andreasronge andreasronge committed Apr 23, 2012
@@ -119,6 +119,11 @@ def destroy_all
end
end
+ # Returns if the entity is currently being updated or created
+ def create_or_updating?
+ !!@_create_or_updating
+ end
+
protected
def update
@@ -128,15 +133,20 @@ def update
end
def create_or_update
+ # since the same model can be created or updated twice from a relationship we have to have this guard
+ @_create_or_updating = true
result = persisted? ? update : create
unless result != false
Neo4j::Rails::Transaction.fail if Neo4j::Rails::Transaction.running?
false
else
true
end
+ ensure
+ @_create_or_updating = nil
end
+
def set_deleted_properties
@_deleted = true
end
@@ -104,7 +104,7 @@ def end_node=(node)
end
def _persist_node(start_or_end_node)
- (start_or_end_node.new_record? || start_or_end_node.relationships_changed?) ? start_or_end_node.save : true
+ ((start_or_end_node.new_record? || start_or_end_node.relationships_changed?) && !start_or_end_node.create_or_updating?) ? start_or_end_node.save : true
end
end
@@ -128,7 +128,6 @@ class MaxVersion < Neo4j::Rails::Model
end
it "restores an older version with relationships" do
- pending "Does not work with new active model 3.2"
ferarri = SportsCar.create!(:name => 'Ferarri')
ferarri.version(1).incoming(:sports_cars).should be_empty
porsche = SportsCar.create!(:name => 'Porsche')
@@ -0,0 +1,27 @@
+module Regressions
+ require 'spec_helper'
+
+ describe "Issue 172, Save callbacks fire once for every outgoing has_one node" do
+ it "should only call save callback once" do
+ a = Neo4j::Rails::Model.new
+ b = Neo4j::Rails::Model.new
+
+ klass = create_model do
+ has_one(:target1)
+ has_one(:target2)
+ after_save :foobar
+
+ def foobar
+ end
+ end
+
+ c = klass.new
+ c.should_receive(:foobar).once
+ c.target1 = a
+ c.target2 = b
+ c.save
+ end
+
+ end
+
+end
@@ -112,6 +112,9 @@ def wrapper
node.should_receive(:save).and_return(true)
other.should_receive(:save).and_return(true)
+ node.should_receive(:create_or_updating?).and_return(false)
+ other.should_receive(:create_or_updating?).and_return(false)
+
node.write_changed_relationships
new_relationship.start_node.should == node
@@ -147,12 +147,27 @@ def wrapper
node.should_receive(:save).and_return(true)
other.should_receive(:save).and_return(true)
+ node.should_receive(:create_or_updating?).and_return(false)
+ other.should_receive(:create_or_updating?).and_return(false)
+
node.write_changed_relationships
new_relationship.start_node.should == node
new_relationship.end_node.should == other
end
end
+
+ it "should not store the relationship twice" do
+ node.stub(:new_record?).and_return(true)
+ other.stub(:new_record?).and_return(true)
+
+ node.should_not_receive(:save)
+ other.should_not_receive(:save)
+ node.should_receive(:create_or_updating?).and_return(true)
+ other.should_receive(:create_or_updating?).and_return(true)
+
+ node.write_changed_relationships
+ end
end
end
end
@@ -120,10 +120,15 @@ def self.to_s
describe "write_changed_relationships" do
before do
- other_node.should_receive(:save).and_return(true)
+ node.should_receive(:create_or_updating?).and_return(false)
node.should_receive(:save).and_return(true)
+
+ other_node.should_receive(:create_or_updating?).and_return(true)
+ other_node.should_not_receive(:save)
+
node.write_changed_relationships
+
node.stub(:persisted?).and_return(true)
node.stub(:new_record?).and_return(false)
end

0 comments on commit ec64019

Please sign in to comment.