Skip to content
Browse files

Fixed validation on Rails relationship - If a rails relationship is i…

…nvalid then the start and end node of that relationship will also be invalid
  • Loading branch information...
1 parent bae7d50 commit 01448365d3125f8b0ca205e9a7702d94731a9982 @andreasronge andreasronge committed Apr 10, 2011
Showing with 90 additions and 20 deletions.
  1. +3 −1 lib/neo4j/rails/relationship.rb
  2. +6 −4 lib/neo4j/rails/relationships/storage.rb
  3. +71 −15 spec/rails/relationship_spec.rb
  4. +10 −0 spec/spec_helper.rb
View
4 lib/neo4j/rails/relationship.rb
@@ -4,6 +4,8 @@ class Relationship
include Neo4j::RelationshipMixin
attr_reader :type
+ attr_writer :start_node
+ attr_writer :end_node
index :_classname
@@ -33,7 +35,7 @@ def id
_java_rel.nil? || neo_id.nil? ? nil : neo_id.to_s
end
- def start_node
+ def start_node
@start_node ||= _java_rel && _java_rel.start_node
end
View
10 lib/neo4j/rails/relationships/storage.rb
@@ -133,21 +133,23 @@ def valid?(context, validated_nodes)
return true if validated_nodes.include?(@node)
all_valid = true
- !@outgoing_rels.each do |rel|
+ @outgoing_rels.each do |rel|
start_node = rel.start_node
end_node = rel.end_node
- #start_node, end_node = end_node, start_node if @node == end_node
validated_nodes << start_node << end_node
if !end_node.valid?(context, validated_nodes)
- all_valid = false
+ all_valid = false
start_node.errors[@rel_type.to_sym] ||= []
start_node.errors[@rel_type.to_sym] << end_node.errors.clone
elsif !start_node.valid?(context, validated_nodes)
- all_valid = false
+
+ all_valid = false
end_node.errors[@rel_type.to_sym] ||= []
end_node.errors[@rel_type.to_sym] << start_node.errors.clone
end
+
+ all_valid = false if !rel.valid?
end
all_valid
end
View
86 spec/rails/relationship_spec.rb
@@ -892,19 +892,75 @@ def to_s
@start_node.rels(:foobar).outgoing.size.should == 1
end
end
-end
-# context "other_node_rel" do
-# subject { @start_node.other_node_rel }
-#
-# before(:each) do
-# @start_node = NodeWithRelationship.new
-# @end_node = Neo4j::Rails::Model.new
-# @start_node.other_node = @end_node
-# end
-#
-# #it { should be_a(RelationshipWithNoProperty) }
-# it_should_behave_like "a relationship model"
-# end
-#
-#end
+ describe "Relationship validation" do
+ before(:all) do
+ @actor_class = create_model
+ @movie_class = create_model
+ @role_class = create_rel_model
+ @role_class.property :character
+ @role_class.validates_presence_of :character
+ @actor_class.has_n(:acted_in).relationship(@role_class)
+ end
+
+ it "validation when invalid" do
+ actor = @actor_class.new
+ movie = @movie_class.new
+ actor.acted_in << movie
+ actor.outgoing(:acted_in).size.should == 1
+ movie.incoming(:acted_in).size.should == 1
+ actor.acted_in.size.should == 1
+ actor.save.should be_false
+ actor.outgoing(:acted_in).size.should == 1
+ movie.incoming(:acted_in).size.should == 1
+ actor.acted_in.size.should == 1
+ rel = actor.acted_in_rels.first
+ rel.errors.size.should == 1
+ rel.should_not be_persisted
+ @actor_class.find(actor.neo_id).should be_nil
+ @movie_class.find(movie.neo_id).should be_nil
+ actor.reload
+ movie.reload
+ actor.outgoing(:acted_in).size.should == 0
+ movie.incoming(:acted_in).size.should == 0
+ actor.acted_in.size.should == 0
+ end
+
+
+ it "validation when invalid with depth 2" do
+ pending "not sure how this will work"
+ actor = @actor_class.new
+ movie = @movie_class.new
+ actor.acted_in << movie
+ role = actor.acted_in_rels.first
+ role.character = 'micky mouse'
+ actor2 = @actor_class.new
+ actor2.acted_in << movie
+ actor.save.should be_false # should probably return false here since we tried to save relationship for actor2
+ end
+
+ it "validation when valid" do
+ actor = @actor_class.new
+ movie = @movie_class.new
+ actor.acted_in << movie
+ role = actor.acted_in_rels.first
+ role.character = 'micky mouse'
+ actor.outgoing(:acted_in).size.should == 1
+ movie.incoming(:acted_in).size.should == 1
+ actor.acted_in.size.should == 1
+ actor.save.should be_true
+ actor.outgoing(:acted_in).size.should == 1
+ movie.incoming(:acted_in).size.should == 1
+ actor.acted_in.size.should == 1
+ rel = actor.acted_in_rels.first
+ rel.errors.size.should == 0
+ rel.should be_persisted
+ actor = @actor_class.find(actor.neo_id)
+ movie = @movie_class.find(movie.neo_id)
+ actor.outgoing(:acted_in).size.should == 1
+ movie.incoming(:acted_in).size.should == 1
+ actor.acted_in.size.should == 1
+ end
+
+ end
+end
View
10 spec/spec_helper.rb
@@ -105,6 +105,16 @@ def create_model(base_class = Neo4j::Model, &block)
klass
end
+ def create_rel_model(base_class = Neo4j::Rails::Relationship, &block)
+ @@_rel_counter ||= 1
+ name ||= "Relationship_#{@@_rel_counter}"
+ @@_rel_counter += 1
+ klass = Class.new(base_class)
+ TempModel.set(klass, name)
+ klass.class_eval &block if block
+ klass
+ end
+
def create_node_mixin_subclass(parent_clazz = Object, &block)
klass = Class.new(parent_clazz)
TempModel.set(klass)

0 comments on commit 0144836

Please sign in to comment.
Something went wrong with that request. Please try again.