active_node 2.2.10 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/lib/active_node/associations/association.rb +9 -3
- data/lib/active_node/graph.rb +31 -9
- data/lib/active_node/version.rb +1 -1
- data/spec/functional/associations_spec.rb +17 -0
- data/spec/functional/graph_spec.rb +21 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 23634528e561c3566ceadee3c51e59b9b1a3f168
|
4
|
+
data.tar.gz: a2f28a259c39e95dacbf8ae3c407aa81dea03454
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 620475b5a57080c67baf074098d4db30672a75877fca13a52211f308c6a5a2fe26d97d87f7727ae58be24f15383270bb432b3b8f43274928c48830f55f463837
|
7
|
+
data.tar.gz: 1b46d6c1b24082e8bde6a912fccec63d4239ba30c87051834f70c385b6d89c3ba4468e0574ba3c0ec1824144d5d5a016c32cf8085f1fe9c3cbfb8b85111ce7f4
|
data/.travis.yml
CHANGED
@@ -41,6 +41,7 @@ module ActiveNode
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def rel(*associations)
|
44
|
+
@loaded = true
|
44
45
|
owner.includes!(reflection.name => associations)
|
45
46
|
end
|
46
47
|
|
@@ -53,7 +54,7 @@ module ActiveNode
|
|
53
54
|
end
|
54
55
|
|
55
56
|
def validate_type(records)
|
56
|
-
unless records.all? {|r| r.is_a?(reflection.klass)}
|
57
|
+
unless records.all? { |r| r.is_a?(reflection.klass) }
|
57
58
|
raise ArgumentError, "#{reflection.name} can only accept object(s) of class #{reflection.klass}"
|
58
59
|
end
|
59
60
|
end
|
@@ -78,14 +79,19 @@ module ActiveNode
|
|
78
79
|
|
79
80
|
|
80
81
|
def rels_reader(*args)
|
81
|
-
rel(*args) unless @
|
82
|
+
rel(*args) unless @loaded
|
82
83
|
@rel_target ||= []
|
83
84
|
end
|
84
85
|
|
85
86
|
def rels_writer(rels)
|
86
|
-
@target = nil
|
87
87
|
@dirty = true
|
88
|
+
rels_loader(rels)
|
89
|
+
end
|
90
|
+
|
91
|
+
def rels_loader(rels)
|
92
|
+
@target = nil
|
88
93
|
@rel_target = rels
|
94
|
+
@loaded = true
|
89
95
|
end
|
90
96
|
|
91
97
|
def save(fresh=false)
|
data/lib/active_node/graph.rb
CHANGED
@@ -166,25 +166,47 @@ module ActiveNode
|
|
166
166
|
|
167
167
|
def parse_results data
|
168
168
|
@records = data.reduce(Set.new) { |set, record| set << wrap(record.first, @klass) }.to_a
|
169
|
-
|
170
|
-
|
169
|
+
parse_nodes(data)
|
170
|
+
parse_relationships(data)
|
171
171
|
@loaded = true
|
172
172
|
end
|
173
173
|
|
174
|
-
def
|
175
|
-
data
|
176
|
-
|
177
|
-
|
178
|
-
|
174
|
+
def parse_nodes(data)
|
175
|
+
each_row_reflection_with_index(data) do |row, reflection, index|
|
176
|
+
node = row[index+2]
|
177
|
+
wrap node, reflection.klass if node.present?
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def parse_relationships(data)
|
182
|
+
each_row_reflection_with_index(data) do |row, reflection, index|
|
183
|
+
rel = row[index+1]
|
184
|
+
if rel.nil?
|
185
|
+
node = row[index]
|
186
|
+
add_empty_assoc(node, reflection) if node
|
187
|
+
elsif rel.present?
|
188
|
+
wrap_rel [rel].flatten.last, reflection
|
179
189
|
end
|
180
190
|
end
|
181
191
|
end
|
182
192
|
|
193
|
+
def each_row_reflection_with_index(data)
|
194
|
+
data.each { |row| @reflections.each_with_index { |reflection, index| yield row, reflection, 2*index } }
|
195
|
+
end
|
196
|
+
|
183
197
|
def previously_loaded?(assoc)
|
184
198
|
@loaded_assoc_cache[assoc] = assoc.rel_target unless @loaded_assoc_cache.key? assoc
|
185
199
|
@loaded_assoc_cache[assoc]
|
186
200
|
end
|
187
201
|
|
202
|
+
def add_empty_assoc(record, reflection)
|
203
|
+
association(extract_id(record), reflection).rels_loader []
|
204
|
+
end
|
205
|
+
|
206
|
+
def association(node_id, reflection)
|
207
|
+
@object_cache[node_id].association(reflection.name)
|
208
|
+
end
|
209
|
+
|
188
210
|
def wrap(record, klass)
|
189
211
|
@object_cache[extract_id record] ||= ActiveNode::Base.wrap(record, klass)
|
190
212
|
end
|
@@ -195,8 +217,8 @@ module ActiveNode
|
|
195
217
|
|
196
218
|
def create_rel(rel, reflection)
|
197
219
|
ActiveNode::Relationship.new(@object_cache[node_id rel, reflection, :other], data(rel)).tap do |relationship|
|
198
|
-
assoc =
|
199
|
-
assoc.
|
220
|
+
assoc = association(node_id(rel, reflection, :owner), reflection)
|
221
|
+
assoc.rels_loader((assoc.rel_target || []) << relationship) unless previously_loaded?(assoc)
|
200
222
|
end
|
201
223
|
end
|
202
224
|
|
data/lib/active_node/version.rb
CHANGED
@@ -186,5 +186,22 @@ describe ActiveNode::Associations do
|
|
186
186
|
father.update_attributes(name: "John")
|
187
187
|
expect(Person.find(father.id).children).to be_empty?
|
188
188
|
end
|
189
|
+
|
190
|
+
it 'should respect object identity on retrieval with includes' do
|
191
|
+
child1 = Person.create!
|
192
|
+
father = Person.create! children: [child1]
|
193
|
+
father = Person.includes(children: :father).find(father.id)
|
194
|
+
father.update_attributes(name: "John")
|
195
|
+
expect(father.children.first.father.name).to eq "John"
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'should respect object identity on retrieval on demand' do
|
199
|
+
pending
|
200
|
+
child1 = Person.create!
|
201
|
+
father = Person.create! children: [child1]
|
202
|
+
father = Person.find(father.id)
|
203
|
+
father.children.first.father.update_attributes(name: "John")
|
204
|
+
expect(father.name).to eq "John"
|
205
|
+
end
|
189
206
|
end
|
190
207
|
end
|
@@ -22,8 +22,21 @@ describe ActiveNode::Graph do
|
|
22
22
|
expect(g_person.children).to eq([c1, c2])
|
23
23
|
end
|
24
24
|
|
25
|
-
it "should not query db twice" do
|
26
|
-
|
25
|
+
it "should not query db twice non empty associations" do
|
26
|
+
person = Person.create!(children: [Person.create!])
|
27
|
+
person = Person.includes(:children).find(person.id)
|
28
|
+
expect(ActiveNode::Neo).not_to receive(:db)
|
29
|
+
person.children
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should not query db twice empty associations" do
|
33
|
+
person = Person.create!
|
34
|
+
person.children
|
35
|
+
expect(ActiveNode::Neo).not_to receive(:db)
|
36
|
+
person.children
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should not query db twice empty associations after load with includes" do
|
27
40
|
person = Person.create!
|
28
41
|
person.includes! :children
|
29
42
|
expect(ActiveNode::Neo).not_to receive(:db)
|
@@ -51,10 +64,15 @@ describe ActiveNode::Graph do
|
|
51
64
|
|
52
65
|
it "should return correct associated objects" do
|
53
66
|
child1 = Person.create! children: [Person.create!, Person.create!]
|
54
|
-
|
67
|
+
address = Address.create!
|
68
|
+
person = Person.create! children: [child1], address: address
|
55
69
|
expect(Person.includes(children: :children).find(person.id).children).to eq([child1])
|
56
70
|
expect(Person.includes(children: 2).find(person.id).children).to eq([child1])
|
57
71
|
expect(Person.includes(children: '*').find(person.id).children).to eq([child1])
|
72
|
+
expect(Person.includes(children: '*0..').find(person.id).children).to eq([child1])
|
73
|
+
person = Person.includes({children: '*0..'} => :address).find(person.id)
|
74
|
+
expect(ActiveNode::Neo).not_to receive(:db)
|
75
|
+
expect(person.address).to eq(address)
|
58
76
|
end
|
59
77
|
end
|
60
78
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_node
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Heinrich Klobuczek
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-01-
|
11
|
+
date: 2015-01-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: active_attr
|