neoid 0.0.51 → 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +35 -0
- data/README.md +148 -47
- data/TODO.md +0 -2
- data/lib/neoid.rb +90 -13
- data/lib/neoid/batch.rb +168 -0
- data/lib/neoid/config.rb +6 -0
- data/lib/neoid/middleware.rb +4 -2
- data/lib/neoid/model_additions.rb +60 -15
- data/lib/neoid/model_config.rb +2 -0
- data/lib/neoid/node.rb +103 -54
- data/lib/neoid/relationship.rb +88 -53
- data/lib/neoid/version.rb +1 -1
- data/spec/neoid/batch_spec.rb +170 -0
- data/spec/neoid/config_spec.rb +13 -0
- data/spec/neoid/model_additions_spec.rb +111 -17
- data/spec/neoid/search_spec.rb +0 -1
- data/spec/neoid_spec.rb +7 -1
- data/spec/spec_helper.rb +11 -9
- data/spec/support/models.rb +12 -3
- data/spec/support/schema.rb +4 -0
- metadata +8 -2
data/lib/neoid/relationship.rb
CHANGED
@@ -1,59 +1,100 @@
|
|
1
1
|
module Neoid
|
2
2
|
module Relationship
|
3
|
+
# this is a proxy that delays loading of start_node and end_node from Neo4j until accessed.
|
4
|
+
# the original Neography Relatioship loaded them on initialization
|
5
|
+
class RelationshipLazyProxy < ::Neography::Relationship
|
6
|
+
def start_node
|
7
|
+
@start_node_from_db ||= @start_node = Neography::Node.load(@start_node, Neoid.db)
|
8
|
+
end
|
9
|
+
|
10
|
+
def end_node
|
11
|
+
@end_node_from_db ||= @end_node = Neography::Node.load(@end_node, Neoid.db)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.from_hash(hash)
|
16
|
+
relationship = RelationshipLazyProxy.new(hash)
|
17
|
+
|
18
|
+
relationship
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
module ClassMethods
|
23
|
+
def delete_command
|
24
|
+
:delete_relationship
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
3
28
|
module InstanceMethods
|
4
29
|
def neo_find_by_id
|
5
|
-
Neoid.db.
|
6
|
-
|
7
|
-
|
30
|
+
results = Neoid.db.get_relationship_auto_index(Neoid::UNIQUE_ID_KEY, self.neo_unique_id)
|
31
|
+
relationship = results.present? ? Neoid::Relationship.from_hash(results[0]) : nil
|
32
|
+
relationship
|
8
33
|
end
|
9
34
|
|
10
|
-
def
|
35
|
+
def _neo_save
|
11
36
|
return unless Neoid.enabled?
|
12
|
-
@_neo_destroyed = false
|
13
37
|
|
14
38
|
options = self.class.neoid_config.relationship_options
|
15
39
|
|
16
|
-
|
17
|
-
|
40
|
+
start_item = self.send(options[:start_node])
|
41
|
+
end_item = self.send(options[:end_node])
|
18
42
|
|
19
|
-
return unless
|
43
|
+
return unless start_item && end_item
|
44
|
+
|
45
|
+
# initialize nodes
|
46
|
+
start_item.neo_node
|
47
|
+
end_item.neo_node
|
20
48
|
|
21
|
-
data = self.to_neo.merge(ar_type: self.class.name, ar_id: self.id)
|
49
|
+
data = self.to_neo.merge(ar_type: self.class.name, ar_id: self.id, Neoid::UNIQUE_ID_KEY => self.neo_unique_id)
|
22
50
|
data.reject! { |k, v| v.nil? }
|
23
|
-
|
24
|
-
relationship = Neography::Relationship.create(
|
25
|
-
options[:type].is_a?(Proc) ? options[:type].call(self) : options[:type],
|
26
|
-
start_node.neo_node,
|
27
|
-
end_node.neo_node,
|
28
|
-
data
|
29
|
-
)
|
30
|
-
|
31
|
-
Neoid.db.add_relationship_to_index(self.class.neo_index_name, :ar_id, self.id, relationship)
|
32
51
|
|
33
|
-
|
52
|
+
rel_type = options[:type].is_a?(Proc) ? options[:type].call(self) : options[:type]
|
53
|
+
|
54
|
+
gremlin_query = <<-GREMLIN
|
55
|
+
idx = g.idx('relationship_auto_index');
|
56
|
+
q = null;
|
57
|
+
if (idx) q = idx.get(unique_id_key, unique_id);
|
58
|
+
|
59
|
+
relationship = null;
|
60
|
+
if (q && q.hasNext()) {
|
61
|
+
relationship = q.next();
|
62
|
+
relationship_data.each {
|
63
|
+
if (relationship.getProperty(it.key) != it.value) {
|
64
|
+
relationship.setProperty(it.key, it.value);
|
65
|
+
}
|
66
|
+
}
|
67
|
+
} else {
|
68
|
+
node_index = g.idx('node_auto_index');
|
69
|
+
start_node = node_index.get(unique_id_key, start_node_unique_id).next();
|
70
|
+
end_node = node_index.get(unique_id_key, end_node_unique_id).next();
|
71
|
+
|
72
|
+
relationship = g.addEdge(start_node, end_node, rel_type, relationship_data);
|
73
|
+
}
|
74
|
+
|
75
|
+
relationship
|
76
|
+
GREMLIN
|
77
|
+
|
78
|
+
script_vars = {
|
79
|
+
unique_id_key: Neoid::UNIQUE_ID_KEY,
|
80
|
+
relationship_data: data,
|
81
|
+
unique_id: self.neo_unique_id,
|
82
|
+
start_node_unique_id: start_item.neo_unique_id,
|
83
|
+
end_node_unique_id: end_item.neo_unique_id,
|
84
|
+
rel_type: rel_type
|
85
|
+
}
|
86
|
+
|
87
|
+
Neoid::logger.info "Relationship#neo_save #{self.class.name} #{self.id}"
|
34
88
|
|
35
|
-
relationship
|
36
|
-
|
37
|
-
|
38
|
-
def neo_load(relationship)
|
39
|
-
Neography::Relationship.load(relationship)
|
40
|
-
end
|
41
|
-
|
42
|
-
def neo_destroy
|
43
|
-
return if @_neo_destroyed
|
44
|
-
@_neo_destroyed = true
|
45
|
-
return unless neo_relationship
|
46
|
-
Neoid.db.remove_relationship_from_index(self.class.neo_index_name, neo_relationship)
|
47
|
-
neo_relationship.del
|
48
|
-
_reset_neo_representation
|
49
|
-
|
50
|
-
Neoid::logger.info "Relationship#neo_destroy #{self.class.name} #{self.id}, index = #{self.class.neo_index_name}"
|
89
|
+
relationship = Neoid.execute_script_or_add_to_batch gremlin_query, script_vars do |value|
|
90
|
+
Neoid::Relationship.from_hash(value)
|
91
|
+
end
|
51
92
|
|
52
|
-
|
93
|
+
relationship
|
53
94
|
end
|
54
95
|
|
55
|
-
def
|
56
|
-
Neoid.
|
96
|
+
def neo_load(hash)
|
97
|
+
Neoid::Relationship.from_hash(hash)
|
57
98
|
end
|
58
99
|
|
59
100
|
def neo_relationship
|
@@ -64,16 +105,15 @@ module Neoid
|
|
64
105
|
def self.included(receiver)
|
65
106
|
receiver.send :include, Neoid::ModelAdditions
|
66
107
|
receiver.send :include, InstanceMethods
|
108
|
+
receiver.extend ClassMethods
|
67
109
|
|
68
|
-
receiver.
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
Neoid.relationship_models << receiver
|
76
|
-
end
|
110
|
+
initialize_relationship receiver if Neoid.env_loaded
|
111
|
+
|
112
|
+
Neoid.relationship_models << receiver
|
113
|
+
end
|
114
|
+
|
115
|
+
def self.meta_data
|
116
|
+
@meta_data ||= {}
|
77
117
|
end
|
78
118
|
|
79
119
|
def self.initialize_relationship(rel_model)
|
@@ -90,7 +130,6 @@ module Neoid
|
|
90
130
|
# e.g. User has_many :likes, after_remove: ...
|
91
131
|
full_callback_name = "after_remove_for_#{this_has_many.name}"
|
92
132
|
belongs_to.klass.send(full_callback_name) << :neo_after_relationship_remove if belongs_to.klass.method_defined?(full_callback_name)
|
93
|
-
# belongs_to.klass.send(:has_many, this_has_many.name, this_has_many.options.merge(after_remove: :neo_after_relationship_remove))
|
94
133
|
|
95
134
|
# has_many (with through) on the side of the relationship that removes a relationship. e.g. User has_many :movies, through :likes
|
96
135
|
many_to_many = all_has_many.find { |o| o.options[:through] == this_has_many.name }
|
@@ -104,24 +143,20 @@ module Neoid
|
|
104
143
|
# movie_id
|
105
144
|
foreign_key_of_record = many_to_many.source_reflection.foreign_key
|
106
145
|
|
107
|
-
(Neoid.
|
146
|
+
(Neoid::Relationship.meta_data ||= {}).tap do |data|
|
108
147
|
(data[belongs_to.klass.name.to_s] ||= {}).tap do |model_data|
|
109
148
|
model_data[many_to_many.klass.name.to_s] = [rel_model.name.to_s, foreign_key_of_owner, foreign_key_of_record]
|
110
149
|
end
|
111
150
|
end
|
112
151
|
|
113
|
-
# puts Neoid.config[:relationship_meta_data].inspect
|
114
|
-
|
115
152
|
# e.g. User has_many :movies, through: :likes, before_remove: ...
|
116
153
|
full_callback_name = "before_remove_for_#{many_to_many.name}"
|
117
154
|
belongs_to.klass.send(full_callback_name) << :neo_before_relationship_through_remove if belongs_to.klass.method_defined?(full_callback_name)
|
118
|
-
# belongs_to.klass.send(:has_many, many_to_many.name, many_to_many.options.merge(before_remove: :neo_after_relationship_remove))
|
119
155
|
|
120
156
|
|
121
157
|
# e.g. User has_many :movies, through: :likes, after_remove: ...
|
122
158
|
full_callback_name = "after_remove_for_#{many_to_many.name}"
|
123
159
|
belongs_to.klass.send(full_callback_name) << :neo_after_relationship_through_remove if belongs_to.klass.method_defined?(full_callback_name)
|
124
|
-
# belongs_to.klass.send(:has_many, many_to_many.name, many_to_many.options.merge(after_remove: :neo_after_relationship_remove))
|
125
160
|
end
|
126
161
|
end
|
127
162
|
end
|
data/lib/neoid/version.rb
CHANGED
@@ -0,0 +1,170 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Neoid::ModelAdditions do
|
4
|
+
context "promises" do
|
5
|
+
it "should run scripts in a batch and return results" do
|
6
|
+
Neoid.batch do |batch|
|
7
|
+
batch << [:execute_script, "1"]
|
8
|
+
batch << [:execute_script, "2"]
|
9
|
+
end.then do |results|
|
10
|
+
results.should == [1, 2]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should run scripts in a batch with batch_size and flush batch when it's full" do
|
15
|
+
Neoid.batch(batch_size: 3) do |batch|
|
16
|
+
(0...9).each do |i|
|
17
|
+
batch.count.should == i % 3
|
18
|
+
batch << [:execute_script, i.to_s]
|
19
|
+
if i % 3 == 0
|
20
|
+
batch.results.count.should == i
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should run scripts in a batch with batch_size and return all results" do
|
27
|
+
Neoid.batch(batch_size: 2) do |batch|
|
28
|
+
(1..6).each do |i|
|
29
|
+
batch << [:execute_script, i.to_s]
|
30
|
+
end
|
31
|
+
end.then do |results|
|
32
|
+
results.should == [1, 2, 3, 4, 5, 6]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should return results then process them" do
|
37
|
+
node_1 = Neoid.db.create_node
|
38
|
+
node_2 = Neoid.db.create_node
|
39
|
+
rel = Neoid.db.create_relationship(:related, node_1, node_2)
|
40
|
+
|
41
|
+
Neoid.batch do |batch|
|
42
|
+
batch << [:execute_script, "g.v(neo_id)", neo_id: node_1['self'].split('/').last.to_i]
|
43
|
+
batch << [:execute_script, "g.v(neo_id)", neo_id: node_2['self'].split('/').last]
|
44
|
+
batch << [:execute_script, "g.e(neo_id)", neo_id: rel['self'].split('/').last]
|
45
|
+
end.then do |results|
|
46
|
+
results[0].should be_a(Neography::Node)
|
47
|
+
results[1].should be_a(Neography::Node)
|
48
|
+
results[2].should be_a(Neography::Relationship)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should remember what to do after each script has executed, and perform it when batch is flushed" do
|
53
|
+
then_results = []
|
54
|
+
|
55
|
+
Neoid.batch do |batch|
|
56
|
+
(batch << [:execute_script, "1"]).then { |res| then_results << res }
|
57
|
+
(batch << [:execute_script, "2"]).then { |res| then_results << res }
|
58
|
+
batch << [:execute_script, "3"]
|
59
|
+
(batch << [:execute_script, "4"]).then { |res| then_results << res }
|
60
|
+
end.then do |results|
|
61
|
+
results.should == [1, 2, 3, 4]
|
62
|
+
then_results.should == [1, 2, 4]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context "nodes" do
|
68
|
+
it "should not execute until batch is done" do
|
69
|
+
u1 = u2 = nil
|
70
|
+
|
71
|
+
res = Neoid.batch do
|
72
|
+
u1 = User.create!(name: "U1")
|
73
|
+
u2 = User.create!(name: "U2")
|
74
|
+
|
75
|
+
u1.neo_find_by_id.should be_nil
|
76
|
+
u2.neo_find_by_id.should be_nil
|
77
|
+
end
|
78
|
+
|
79
|
+
res.length.should == 2
|
80
|
+
|
81
|
+
u1.neo_find_by_id.should_not be_nil
|
82
|
+
u2.neo_find_by_id.should_not be_nil
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should update nodes in batch" do
|
86
|
+
u1 = User.create!(name: "U1")
|
87
|
+
u2 = User.create!(name: "U2")
|
88
|
+
|
89
|
+
res = Neoid.batch do
|
90
|
+
u1.name = "U1 update"
|
91
|
+
u2.name = "U2 update"
|
92
|
+
|
93
|
+
u1.save!
|
94
|
+
u2.save!
|
95
|
+
|
96
|
+
u1.neo_find_by_id.name.should == "U1"
|
97
|
+
u2.neo_find_by_id.name.should == "U2"
|
98
|
+
end
|
99
|
+
|
100
|
+
res.length.should == 2
|
101
|
+
|
102
|
+
u1.neo_find_by_id.name.should == "U1 update"
|
103
|
+
u2.neo_find_by_id.name.should == "U2 update"
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
# Not working yet because Neography can't delete a node and all of its realtionships in a batch, and deleting a node with relationships results an error
|
108
|
+
# it "should delete nodes in batch" do
|
109
|
+
# u1 = User.create!(name: "U1")
|
110
|
+
# u2 = User.create!(name: "U2")
|
111
|
+
|
112
|
+
# res = Neoid.batch do
|
113
|
+
# u1_node_id = u1.neo_find_by_id.neo_id
|
114
|
+
# u2_node_id = u2.neo_find_by_id.neo_id
|
115
|
+
|
116
|
+
# u1.destroy
|
117
|
+
# u2.destroy
|
118
|
+
|
119
|
+
# Neoid.db.get_node(u1_node_id).should_not be_nil
|
120
|
+
# Neoid.db.get_node(u2_node_id).should_not be_nil
|
121
|
+
# end
|
122
|
+
|
123
|
+
# res.length.should == 2
|
124
|
+
|
125
|
+
# Neoid.db.get_node(u1_node_id).should be_nil
|
126
|
+
# Neoid.db.get_node(u2_node_id).should be_nil
|
127
|
+
# end
|
128
|
+
end
|
129
|
+
|
130
|
+
context "relationships" do
|
131
|
+
let(:user) { User.create(name: "Elad Ossadon", slug: "elado") }
|
132
|
+
let(:movie) { Movie.create(name: "Memento", slug: "memento-1999", year: 1999) }
|
133
|
+
|
134
|
+
it "should not execute until batch is done" do
|
135
|
+
# ensure user and movie nodes are inserted
|
136
|
+
user
|
137
|
+
movie
|
138
|
+
|
139
|
+
res = Neoid.batch do |batch|
|
140
|
+
user.like! movie
|
141
|
+
|
142
|
+
user.likes.last.neo_find_by_id.should be_nil
|
143
|
+
end
|
144
|
+
|
145
|
+
res.length.should == 1
|
146
|
+
|
147
|
+
user.likes.last.neo_find_by_id.should_not be_nil
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should not execute until batch is done" do
|
151
|
+
# ensure user and movie nodes are inserted
|
152
|
+
user
|
153
|
+
movie
|
154
|
+
|
155
|
+
# then destroy the nodes, allow the relationship do that in the batch
|
156
|
+
user.neo_destroy
|
157
|
+
movie.neo_destroy
|
158
|
+
|
159
|
+
res = Neoid.batch do |batch|
|
160
|
+
user.like! movie
|
161
|
+
|
162
|
+
user.likes.last.neo_find_by_id.should be_nil
|
163
|
+
end
|
164
|
+
|
165
|
+
res.length.should == 3
|
166
|
+
|
167
|
+
user.likes.last.neo_find_by_id.should_not be_nil
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
@@ -1,16 +1,15 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'fileutils'
|
3
2
|
|
4
3
|
describe Neoid::ModelAdditions do
|
5
4
|
context "nodes" do
|
6
5
|
context "create graph nodes" do
|
7
|
-
it "should call
|
8
|
-
User.
|
9
|
-
|
10
|
-
|
6
|
+
it "should call neo_save after model creation" do
|
7
|
+
user = User.new(name: "Elad Ossadon")
|
8
|
+
user.should_receive(:neo_save)
|
9
|
+
user.save!
|
11
10
|
end
|
12
11
|
|
13
|
-
it "should create a
|
12
|
+
it "should create a node for user" do
|
14
13
|
user = User.create!(name: "Elad Ossadon", slug: "elado")
|
15
14
|
|
16
15
|
user.neo_node.should_not be_nil
|
@@ -22,7 +21,7 @@ describe Neoid::ModelAdditions do
|
|
22
21
|
|
23
22
|
it "should create a neo_node for movie" do
|
24
23
|
movie = Movie.create!(name: "Memento", slug: "memento-1999", year: 1999)
|
25
|
-
|
24
|
+
|
26
25
|
movie.neo_node.should_not be_nil
|
27
26
|
|
28
27
|
movie.neo_node.ar_id.should == movie.id
|
@@ -31,26 +30,110 @@ describe Neoid::ModelAdditions do
|
|
31
30
|
end
|
32
31
|
end
|
33
32
|
|
33
|
+
context "update graph nodes" do
|
34
|
+
it "should call neo_save after model update" do
|
35
|
+
user = User.create!(name: "Elad Ossadon")
|
36
|
+
user.should_receive(:neo_save)
|
37
|
+
user.name = "John Doe"
|
38
|
+
user.save!
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should update a node after model update" do
|
42
|
+
user = User.create!(name: "Elad Ossadon")
|
43
|
+
user.neo_node.name.should == "Elad Ossadon"
|
44
|
+
|
45
|
+
user.name = "John Doe"
|
46
|
+
user.save!
|
47
|
+
|
48
|
+
user.neo_node.name.should == "John Doe"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
34
52
|
context "find by id" do
|
35
53
|
it "should find a neo_node for user" do
|
36
54
|
user = User.create!(name: "Elad Ossadon", slug: "elado")
|
37
|
-
|
55
|
+
|
38
56
|
user.neo_node.should_not be_nil
|
39
57
|
user.neo_find_by_id.should_not be_nil
|
40
58
|
end
|
41
59
|
end
|
60
|
+
|
61
|
+
context "no auto_index" do
|
62
|
+
it "should not index a node if option :auto_index is set to false" do
|
63
|
+
model = NoAutoIndexNode.new(name: "Hello")
|
64
|
+
model.should_not_receive(:neo_save)
|
65
|
+
model.save!
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "subrefs" do
|
70
|
+
it "should create a relationship with a subref node" do
|
71
|
+
old, Neoid.config.enable_subrefs = Neoid.config.enable_subrefs, true
|
72
|
+
|
73
|
+
Neoid.send(:initialize_subrefs)
|
74
|
+
|
75
|
+
begin
|
76
|
+
user = User.create!(name: "Elad")
|
77
|
+
user.neo_node.rel(:incoming, :users_subref).should_not be_nil
|
78
|
+
ensure
|
79
|
+
Neoid.config.enable_subrefs = old
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should not create a relationship with a subref node if disabled" do
|
84
|
+
old, Neoid.config.enable_subrefs = Neoid.config.enable_subrefs, false
|
85
|
+
|
86
|
+
begin
|
87
|
+
user = User.create!(name: "Elad")
|
88
|
+
user.neo_node.rel(:incoming, :users_subref).should be_nil
|
89
|
+
ensure
|
90
|
+
Neoid.config.enable_subrefs = old
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context "per_model_indexes" do
|
96
|
+
it "should create a relationship with a subref node" do
|
97
|
+
old, Neoid.config.enable_per_model_indexes = Neoid.config.enable_per_model_indexes, true
|
98
|
+
|
99
|
+
Neoid.send(:initialize_per_model_indexes)
|
100
|
+
|
101
|
+
begin
|
102
|
+
user = User.create!(name: "Elad")
|
103
|
+
Neoid.db.get_node_index(User.neo_model_index_name, 'ar_id', user.id).should_not be_nil
|
104
|
+
ensure
|
105
|
+
Neoid.config.enable_per_model_indexes = old
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should not create a relationship with a subref node if disabled" do
|
110
|
+
old, Neoid.config.enable_per_model_indexes = Neoid.config.enable_per_model_indexes, false
|
111
|
+
|
112
|
+
begin
|
113
|
+
user = User.create!(name: "Elad")
|
114
|
+
expect { Neoid.db.get_node_index(User.neo_model_index_name, 'ar_id', user.id) }.to raise_error(Neography::NotFoundException)
|
115
|
+
ensure
|
116
|
+
Neoid.config.enable_per_model_indexes = old
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
42
120
|
end
|
43
121
|
|
44
122
|
context "relationships" do
|
45
|
-
let(:user) { User.create(name: "Elad Ossadon", slug: "elado") }
|
46
|
-
let(:movie) { Movie.create(name: "Memento", slug: "memento-1999", year: 1999) }
|
123
|
+
let(:user) { User.create!(name: "Elad Ossadon", slug: "elado") }
|
124
|
+
let(:movie) { Movie.create!(name: "Memento", slug: "memento-1999", year: 1999) }
|
47
125
|
|
48
|
-
it "should
|
126
|
+
it "should call neo_save after relationship model creation" do
|
127
|
+
Like.any_instance.should_receive(:neo_save)
|
49
128
|
user.like! movie
|
50
|
-
|
51
|
-
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should create a neo_relationship for like" do
|
132
|
+
like = user.like! movie
|
133
|
+
like = user.likes.last
|
134
|
+
|
52
135
|
like.neo_find_by_id.should_not be_nil
|
53
|
-
|
136
|
+
|
54
137
|
like.neo_relationship.should_not be_nil
|
55
138
|
|
56
139
|
like.neo_relationship.start_node.should == user.neo_node
|
@@ -63,7 +146,7 @@ describe Neoid::ModelAdditions do
|
|
63
146
|
like = user.likes.last
|
64
147
|
|
65
148
|
relationship_neo_id = like.neo_relationship.neo_id
|
66
|
-
|
149
|
+
|
67
150
|
Neography::Relationship.load(relationship_neo_id).should_not be_nil
|
68
151
|
|
69
152
|
user.unlike! movie
|
@@ -98,12 +181,23 @@ describe Neoid::ModelAdditions do
|
|
98
181
|
user.movie_ids = movies[0...2].collect(&:id)
|
99
182
|
}.to change{ user.neo_node.outgoing(:likes).length }.to(2)
|
100
183
|
end
|
184
|
+
|
185
|
+
it "should update a relationship after relationship model update" do
|
186
|
+
like = user.like! movie
|
187
|
+
|
188
|
+
like.neo_relationship.rate.should be_nil
|
189
|
+
|
190
|
+
like.rate = 10
|
191
|
+
like.save!
|
192
|
+
|
193
|
+
like.neo_relationship.rate.should == 10
|
194
|
+
end
|
101
195
|
end
|
102
196
|
|
103
197
|
context "polymorphic relationship" do
|
104
198
|
let(:user) { User.create(name: "Elad Ossadon", slug: "elado") }
|
105
199
|
|
106
|
-
it "
|
200
|
+
it "should create relationships with polymorphic items" do
|
107
201
|
followed = [
|
108
202
|
User.create(name: "Some One", slug: "someone"),
|
109
203
|
Movie.create(name: "The Prestige"),
|
@@ -112,7 +206,7 @@ describe Neoid::ModelAdditions do
|
|
112
206
|
|
113
207
|
expect {
|
114
208
|
followed.each do |item|
|
115
|
-
user.user_follows.create(item: item)
|
209
|
+
user.user_follows.create!(item: item)
|
116
210
|
end
|
117
211
|
}.to change{ user.neo_node.outgoing(:follows).length }.to(followed.length)
|
118
212
|
|