Skip to content

Commit

Permalink
Merge c202aac into 3e386d5
Browse files Browse the repository at this point in the history
  • Loading branch information
subvertallchris committed Sep 8, 2014
2 parents 3e386d5 + c202aac commit 479c134
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 28 deletions.
26 changes: 21 additions & 5 deletions lib/neo4j/active_rel/persistence.rb
Expand Up @@ -54,10 +54,10 @@ def create!(*args)

def confirm_node_classes
[from_node, to_node].each do |node|
check = from_node == node ? :_from_class : :_to_class
next if self.class.send(check) == :any
unless self.class.send(check) == node.class
raise ModelClassInvalidError, "Node class was #{node.class}, expected #{self.class.send(check)}"
type = from_node == node ? :_from_class : :_to_class
next if allows_any_class?(type)
unless class_as_constant(type) == node.class
raise ModelClassInvalidError, "Node class was #{node.class}, expected #{self.class.send(type)}"
end
end
end
Expand All @@ -68,5 +68,21 @@ def _create_rel(from_node, to_node, *args)
set_classname(props)
from_node.create_rel(type, to_node, props)
end

def class_as_constant(type)
given_class = self.class.send(type)
case
when given_class.is_a?(String)
given_class.constantize
when given_class.is_a?(Symbol)
given_class.to_s.constantize
else
given_class
end
end

def allows_any_class?(type)
self.class.send(type) == :any || self.class.send(type) == false
end
end
end
end
15 changes: 7 additions & 8 deletions lib/neo4j/active_rel/property.rb
@@ -1,4 +1,3 @@

module Neo4j::ActiveRel
module Property
extend ActiveSupport::Concern
Expand All @@ -7,26 +6,26 @@ module Property
%w[to_node from_node].each do |direction|
define_method("#{direction}") { instance_variable_get("@#{direction}") }
define_method("#{direction}=") do |argument|
raise FrozenRelError, "Relationship start/end nodes cannot be changed once persisted" if self.persisted?
raise FrozenRelError, 'Relationship start/end nodes cannot be changed once persisted' if self.persisted?
instance_variable_set("@#{direction}", argument)
end
end

alias_method :start_node, :from_node
alias_method :end_node, :to_node

# @return [String] a string representing the relationship type that will be created
def type
self.class._type
end

def initialize(attributes={}, options={})
def initialize(attributes = {}, options = {})
super(attributes, options)

send_props(@relationship_props) unless @relationship_props.nil?
end

module ClassMethods

# Extracts keys from attributes hash which are relationships of the model
# TODO: Validate separately that relationships are getting the right values? Perhaps also store the values and persist relationships on save?
def extract_association_attributes!(attributes)
Expand All @@ -43,26 +42,26 @@ def extract_association_attributes!(attributes)
alias_method :start_class, :from_class
alias_method :end_class, :to_class

# @param type [String] sets the relationship type when creating relationships via this class
def type(type = nil)
@rel_type = type
end

# @return [String] a string representing the relationship type that will be created
def _type
@rel_type
end

def load_entity(id)
Neo4j::Node.load(id)
end

end

private

def load_nodes(start_node=nil, end_node=nil)
def load_nodes(start_node = nil, end_node = nil)
@from_node = RelatedNode.new(end_node)
@to_node = RelatedNode.new(start_node)
end

end
end
end
32 changes: 28 additions & 4 deletions spec/unit/active_rel/persistence_spec.rb
Expand Up @@ -98,25 +98,49 @@ class ThatClass; end

let(:r) { clazz.new(from_node: this_class_node, to_node: that_class_node) }

it 'does not raise an error' do
def model_stubs_and_expectations
expect(this_class_node).to receive(:class).and_return(ThisClass)
clazz.any_instance.stub(:_create_rel)
clazz.any_instance.stub(:init_on_load)
expect{r.save}.not_to raise_error
end

context 'with :any types' do
it 'does not raise an error' do
model_stubs_and_expectations
end

it 'converts strings to constants' do
clazz.from_class 'ThisClass'
model_stubs_and_expectations
end

it 'converts symbols to constants' do
clazz.from_class :ThisClass
model_stubs_and_expectations
end

context 'with :any or false types' do
before do
clazz.from_class :any
clazz.to_class :any
end

it 'does not check the classes of the nodes' do
def any_stubs_and_expectations
expect(this_class_node).not_to receive(:class)
expect(that_class_node).not_to receive(:class)
clazz.any_instance.stub(:_create_rel)
clazz.any_instance.stub(:init_on_load)
expect{r.save}.not_to raise_error
expect { r.save }.not_to raise_error
end

it 'does not check the classes of the nodes' do
any_stubs_and_expectations
end

it 'accepts false instead of :any' do
clazz.from_class false
clazz.to_class false
any_stubs_and_expectations
end
end
end
Expand Down
14 changes: 3 additions & 11 deletions spec/unit/active_rel/property_spec.rb
Expand Up @@ -55,23 +55,15 @@
expect(clazz.instance_variable_get(:@to_class)).to eq Object
end
end

context 'when passed invalid classes' do
it 'is pending'
end

context 'when passed :any' do
it 'is pending'
end
end
end

describe 'class methods' do
describe 'extract_relationship_attributes!' do
it 'returns the from and to keys and values' do
expect(clazz.extract_association_attributes!({to_node: 'test', from_node: 'test', name: 'chris'})).to eq(to_node: 'test', from_node: 'test')
expect(clazz.extract_association_attributes!({to_node: 'test', name: 'chris'})).to eq(to_node: 'test')
expect(clazz.extract_association_attributes!({from_node: 'test', name: 'chris'})).to eq(from_node: 'test')
expect(clazz.extract_association_attributes!({ to_node: 'test', from_node: 'test', name: 'chris' })).to eq(to_node: 'test', from_node: 'test')
expect(clazz.extract_association_attributes!({ to_node: 'test', name: 'chris' })).to eq(to_node: 'test')
expect(clazz.extract_association_attributes!({ from_node: 'test', name: 'chris' })).to eq(from_node: 'test')
end
end

Expand Down

0 comments on commit 479c134

Please sign in to comment.