Skip to content

Commit

Permalink
Change QueryProxy#associate to #create and allow for creating of rela…
Browse files Browse the repository at this point in the history
…tionships with persisted/unpersisted nodes/arrays of nodes
  • Loading branch information
cheerfulstoic committed Aug 5, 2014
1 parent d3363ad commit 383159a
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 19 deletions.
22 changes: 15 additions & 7 deletions lib/neo4j/active_node/query/query_proxy.rb
Expand Up @@ -79,7 +79,7 @@ def to_cypher

# To add a relationship for the node for the association on this QueryProxy
def <<(other_node)
associate(other_node, {})
create(other_node, {})

self
end
Expand All @@ -90,14 +90,22 @@ def [](index)
self.to_a[index]
end

def associate(other_node, properties)
def create(other_nodes, properties)
if @association
raise ArgumentError, "Node must be of the association's class when model is specified" if @model && other_node.class != @model
other_nodes = [other_nodes].flatten

_association_query_start(:start)
.match(end: other_node.class)
.where(end: {neo_id: other_node.neo_id})
.create("start#{_association_arrow(properties, true)}end").exec
raise ArgumentError, "Node must be of the association's class when model is specified" if @model && other_nodes.any? {|other_node| other_node.class != @model }

other_nodes.each do |other_node|
Neo4j::Transaction.run do |tx|
other_node.save if not other_node.persisted?

_association_query_start(:start)
.match(end: other_node.class)
.where(end: {neo_id: other_node.neo_id})
.create("start#{_association_arrow(properties, true)}end").exec
end
end
else
raise "Can only create associations on associations"
end
Expand Down
51 changes: 41 additions & 10 deletions spec/e2e/has_n_spec.rb
Expand Up @@ -12,6 +12,8 @@
#knows_type = clazz_b
UniqueClass.create do
include Neo4j::ActiveNode
property :name

has_many :both, :friends, model_class: false
has_many :out, :knows, model_class: self
has_many :in, :knows_me, origin: :knows, model_class: self
Expand Down Expand Up @@ -114,19 +116,48 @@
end
end

describe 'me.friends.associate(other, since: 1994)' do
it 'creates a new relationship with given properties' do
r = node.friends.associate(friend1, since: 1994)
describe 'me.friends#create(other, since: 1994)' do
describe "creating relationships to existing nodes" do
it 'creates a new relationship when given existing nodes and given properties' do
node.friends.create(friend1, since: 1994)

r = node.rel(dir: :outgoing, type: '#friends')

r[:since].should eq(1994)
end

it 'creates new relationships when given an array of nodes and given properties' do
node.friends.create([friend1, friend2], since: 1995)

r = node.rel(dir: :outgoing, type: '#friends')
rs = node.rels(dir: :outgoing, type: '#friends')

r[:since].should eq(1994)
rs.map(&:end_node).should =~ [friend1, friend2]
rs.each do |r|
r[:since].should eq(1995)
end
end
end
end

describe "me.friends.create(name: 'Joe')" do
# TODO: Should be able to create both relationship and node off of an association
# Maybe .create / .push for creating relationship / node (respectively)
# Maybe should be able to create relationships by passing either node object or hash of values
describe "creating relationships and nodes at the same time" do
it 'creates a new relationship when given unpersisted node and given properties' do
node.friends.create(clazz_a.new(name: 'Brad'), {since: 1996})

r = node.rel(dir: :outgoing, type: '#friends')

r[:since].should eq(1996)
r.end_node.name.should == 'Brad'
end

it 'creates a new relationship when given an array of unpersisted nodes and given properties' do
node.friends.create([clazz_a.new(name: 'James'), clazz_a.new(name: 'Cat')], {since: 1997})

rs = node.rels(dir: :outgoing, type: '#friends')

rs.map(&:end_node).map(&:name).should =~ ['James', 'Cat']
rs.each do |r|
r[:since].should eq(1997)
end
end
end
end
end
4 changes: 2 additions & 2 deletions spec/e2e/query_spec.rb
Expand Up @@ -243,8 +243,8 @@ class Teacher

context 'othmar likes moster trucks more than samuels' do
before(:each) do
samuels.interests.associate(monster_trucks, intensity: 1)
othmar.interests.associate(monster_trucks, intensity: 11)
samuels.interests.create(monster_trucks, intensity: 1)
othmar.interests.create(monster_trucks, intensity: 11)
end

# Should get both
Expand Down

0 comments on commit 383159a

Please sign in to comment.