active_node 2.2.6 → 2.2.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3416059b31793c6207482121cf2f34de2d24b11f
4
- data.tar.gz: 8286a0af63a32878cfaa64902877c1290899744c
3
+ metadata.gz: 1b61a35ae17f4598504c8840a398430f85c0a6a3
4
+ data.tar.gz: 4ee34af5defc7d4e94f201ffac233ff0ab30344b
5
5
  SHA512:
6
- metadata.gz: 7af0ea851c7d6b59474a3a67eb739c2c76edf424fd7ada60eac28302ca438cacc20a6863f74ed60fc0bf84242af505a905da495d1e5e4996aa595891abe1e41b
7
- data.tar.gz: bfe66442b9408ab7f09946e48813c1741b0158fd73add2b4d0c29144a4f00ef5f13f4a8a81d39b209ca75105e7545ac6d6bdd856bb81792e6d236a68bc25a8ea
6
+ metadata.gz: 1f100b6302c72bc460b5f8149adaaf5bf179bb3dd6b2a84ad5db8bacb12db160ae4ad366243c19bb20a1bee3f90b20b0b11515f9fbd5d97f8c117bc52d5710fd
7
+ data.tar.gz: 7547f7c6a17f49dc5ad264843b16007cd17a1dc28b8f785c9fdb1fb519770eee51ff73a7a4e0b15e82b1ba889a6f4efd3facb3a60bc3d159ba483fae97409c2b
@@ -1,8 +1,8 @@
1
1
  module ActiveNode
2
2
  class Graph
3
- MULTI_VALUE_METHODS = [:includes, :eager_load, :preload, :select, :group,
4
- :order, :joins, :where, :having, :bind, :references,
5
- :extending, :unscope]
3
+ MULTI_VALUE_METHODS = [:includes, :eager_load, :preload, :select, :group,
4
+ :order, :joins, :where, :having, :bind, :references,
5
+ :extending, :unscope]
6
6
 
7
7
  SINGLE_VALUE_METHODS = [:limit, :offset, :lock, :readonly, :from, :reordering,
8
8
  :reverse_order, :distinct, :create_with, :uniq]
@@ -15,6 +15,8 @@ module ActiveNode
15
15
  attr_reader :reflections, :matches, :klass, :loaded
16
16
  alias :loaded? :loaded
17
17
 
18
+ delegate :data, :extract_id, to: ActiveNode::Base
19
+
18
20
  def initialize klass, *includes
19
21
  @klass = klass if klass < ActiveNode::Base
20
22
  @matches = []
@@ -51,7 +53,7 @@ module ActiveNode
51
53
  end
52
54
 
53
55
  def load
54
- parse_results execute unless loaded?
56
+ parse_results execute['data'] unless loaded?
55
57
  self
56
58
  end
57
59
 
@@ -159,30 +161,27 @@ module ActiveNode
159
161
  end
160
162
 
161
163
  def sanitize_where
162
- @where.each { |key, value| @where[key] = extract_id(value) if key.to_s == 'id'}
164
+ @where.each { |key, value| @where[key] = extract_id(value) if key.to_s == 'id' }
163
165
  end
164
166
 
165
167
  def to_cypher
166
168
  [initial_match, conditions, "with n0", order_list, skip_cond, limit_cond, query, 'return', list_with_rel(@reflections.size), order_list_with_defaults].compact.join ' '
167
169
  end
168
170
 
169
- def parse_results results
170
- records = Set.new
171
- results['data'].each do |record|
172
- records << wrap(record.first, @klass)
171
+ def parse_results data
172
+ @records = data.reduce(Set.new) { |set, record| set << wrap(record.first, @klass) }.to_a
173
+ alternate_cells(data, 2) { |node, reflection| wrap node, reflection.klass }
174
+ alternate_cells(data, 1) { |rel, reflection| wrap_rel [rel].flatten.last, reflection }
175
+ @loaded = true
176
+ end
177
+
178
+ def alternate_cells data, shift
179
+ data.each do |row|
173
180
  @reflections.each_with_index do |reflection, index|
174
- node_rel = record[2*index+1]
175
- node_rel = node_rel.last if node_rel.is_a? Array
176
- next unless node_rel
177
- owner = @object_cache[owner_id node_rel, reflection.direction]
178
- node = wrap record[2*index + 2], reflection.klass
179
- rel = reflection.klass.create_rel node_rel, node
180
- assoc = owner.association(reflection.name)
181
- assoc.rels_writer((assoc.rel_target || []) << rel) unless previously_loaded?(assoc)
181
+ cell = row[2*index + shift]
182
+ yield cell, reflection if cell
182
183
  end
183
184
  end
184
- @loaded = true
185
- @records = records.to_a
186
185
  end
187
186
 
188
187
  def previously_loaded?(assoc)
@@ -194,8 +193,19 @@ module ActiveNode
194
193
  @object_cache[extract_id record] ||= ActiveNode::Base.wrap(record, klass)
195
194
  end
196
195
 
197
- def owner_id relationship, direction
198
- extract_id relationship[direction == :incoming ? 'end' : 'start']
196
+ def wrap_rel(rel, reflection)
197
+ @relationship_cache[extract_id rel] ||= create_rel(rel, reflection)
198
+ end
199
+
200
+ def create_rel(rel, reflection)
201
+ ActiveNode::Relationship.new(@object_cache[node_id rel, reflection, :other], data(rel)).tap do |relationship|
202
+ assoc = @object_cache[node_id rel, reflection, :owner].association(reflection.name)
203
+ assoc.rels_writer((assoc.rel_target || []) << relationship) unless previously_loaded?(assoc)
204
+ end
205
+ end
206
+
207
+ def node_id relationship, reflection, side
208
+ extract_id relationship[reflection.direction == {owner: :outgoing, other: :incoming}[side] ? 'start' : 'end']
199
209
  end
200
210
 
201
211
  def parse_paths as, klass, includes
@@ -256,18 +266,5 @@ module ActiveNode
256
266
  end
257
267
  "order by #{build_order(:n0)}"
258
268
  end
259
-
260
- def extract_id(id)
261
- case id
262
- when Array
263
- id.map { |i| extract_id(i) }
264
- when ActiveNode::Base
265
- id.id
266
- else
267
- get_id(id).to_i
268
- end
269
- end
270
-
271
-
272
269
  end
273
270
  end
@@ -31,14 +31,6 @@ module ActiveNode
31
31
  node.is_a?(Array) ? new_instances(node, klass) : new_instance(node, klass)
32
32
  end
33
33
 
34
- def wrap_rel rel, node, klass
35
- create_rel rel, wrap(node, klass)
36
- end
37
-
38
- def create_rel rel, node
39
- ActiveNode::Relationship.new node, rel['data'].merge(id: get_id(rel).to_i)
40
- end
41
-
42
34
  def active_node_class(class_name, default_klass=nil)
43
35
  klass = Module.const_get(class_name) rescue nil
44
36
  klass && klass < ActiveNode::Base && klass || default_klass
@@ -48,15 +40,26 @@ module ActiveNode
48
40
  ActiveNode::Graph.new(self)
49
41
  end
50
42
 
43
+ def data hash
44
+ hash['data'].merge(id: extract_id(hash))
45
+ end
46
+
47
+ def extract_id(id)
48
+ case id
49
+ when Array
50
+ id.map { |i| extract_id(i) }
51
+ when ActiveNode::Base
52
+ id.id
53
+ else
54
+ get_id(id).to_i
55
+ end
56
+ end
57
+
51
58
  private
52
59
  def new_instance node, klass=nil
53
60
  node && (klass || find_suitable_class(Neo.db.get_node_labels(node))).try(:new, data(node), :declared?)
54
61
  end
55
62
 
56
- def data hash
57
- hash['data'].merge(id: get_id(hash).to_i)
58
- end
59
-
60
63
  def new_instances nodes, klass=nil
61
64
  nodes.map { |node| new_instance(node, klass) }.compact
62
65
  end
@@ -203,7 +206,7 @@ module ActiveNode
203
206
  end
204
207
 
205
208
  def create_node_with_label
206
- self.id = get_id(Neo.db.create_node(all_attributes)).to_i
209
+ self.id = self.class.extract_id(Neo.db.create_node(all_attributes))
207
210
  Neo.db.set_label(id, self.class.label)
208
211
  end
209
212
 
@@ -1,3 +1,3 @@
1
1
  module ActiveNode
2
- VERSION = "2.2.6"
2
+ VERSION = "2.2.7"
3
3
  end
@@ -0,0 +1,9 @@
1
+ module Rails
2
+ module Generators
3
+ class GeneratedAttribute
4
+ def type_class
5
+ type.to_s.camelcase
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,55 @@
1
+ Description:
2
+ Creates a new ActiveNode model, using the given NAME. Similar to with
3
+ active_record, pass the model name, either CamelCased or under_scored, and
4
+ an optional list of attribute pairs as arguments.
5
+
6
+ Attribute pairs are attribute:type arguments specifying the model's
7
+ attributes. The +timestamps+ call is added by default, so you don't have to
8
+ a) specify them as explicit attributes, nor b) add the +timestamps+ call
9
+ yourself. You can, however, turn this off by using the +--no-timestamps+
10
+ option.
11
+
12
+ This generator invokes your configured test framework and will, thus,
13
+ create tests for your generated model.
14
+
15
+
16
+ Available field types:
17
+
18
+ Just after the field name you can specify a type like String or boolean.
19
+ It will generate the property key with the associated Neo4J value type. You
20
+ can use the following types:
21
+
22
+ * big_decimal
23
+ * boolean
24
+ * date
25
+ * date_time
26
+ * float
27
+ * integer
28
+ * object
29
+ * string
30
+
31
+ Examples:
32
+
33
+ `rails generate active_node:model Car`
34
+
35
+ Creates:
36
+
37
+ Model: +app/models/car.rb+
38
+ Test: +test/models/car_test.rb+
39
+
40
+ `rails generate active_node:model Car make engine_displacement`
41
+
42
+ This will...
43
+
44
+ ...create app/models/car.rb
45
+ ...add ActiveNode attributes +make+ and +engine_displacement+,
46
+ without specifying the attribute type.
47
+
48
+ `rails generate active_node:model Car make:string engine_displacement:short`
49
+
50
+ This will...
51
+
52
+ * ...app/models/car.rb
53
+ * ...add ActiveNode attributes +make+ as type String, and
54
+ +engine_displacement+ as type short.
55
+
@@ -0,0 +1,25 @@
1
+ require_relative '../../../ext/rails/generators/generated_attribute'
2
+
3
+ module ActiveNode
4
+ class ModelGenerator < Rails::Generators::NamedBase
5
+ source_root File.expand_path('../templates', __FILE__)
6
+ check_class_collision
7
+
8
+ class_option :timestamps,
9
+ type: :boolean,
10
+ default: true
11
+
12
+ hook_for :test_framework,
13
+ as: :model,
14
+ aliases: '-t'
15
+
16
+ argument :attributes,
17
+ type: :array,
18
+ default: [],
19
+ banner: 'attribute[:type] attribute[:type]'
20
+
21
+ def create_model_file
22
+ template 'model.rb.erb', File.join('app/models', class_path, "#{file_name}.rb")
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,10 @@
1
+ <% module_namespacing do -%>
2
+ class <%= class_name %> < ActiveNode::Base
3
+ <% attributes.reject(&:reference?).each do |attribute| -%>
4
+ attribute :<%= attribute.name %>, type: <%= attribute.type_class %>
5
+ <% end -%>
6
+ <% if options[:timestamps] -%>
7
+ timestamps
8
+ <% end -%>
9
+ end
10
+ <% end -%>
@@ -50,5 +50,13 @@ describe ActiveNode::Graph do
50
50
  p = Person.create! father: Person.create!
51
51
  Person.where(id: p.id).includes(:father).first.should == p
52
52
  end
53
+
54
+ it "should return correct associated objects" do
55
+ child1 = Person.create! children: [Person.create!, Person.create!]
56
+ person = Person.create! children: [child1]
57
+ Person.includes(children: :children).find(person.id).children.should == [child1]
58
+ Person.includes(children: 2).find(person.id).children.should == [child1]
59
+ Person.includes(children: '*').find(person.id).children.should == [child1]
60
+ end
53
61
  end
54
62
  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.2.6
4
+ version: 2.2.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Heinrich Klobuczek
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-17 00:00:00.000000000 Z
11
+ date: 2014-09-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: active_attr
@@ -180,6 +180,10 @@ files:
180
180
  - lib/active_node/validations.rb
181
181
  - lib/active_node/validations/uniqueness.rb
182
182
  - lib/active_node/version.rb
183
+ - lib/ext/rails/generators/generated_attribute.rb
184
+ - lib/generators/active_node/model/USAGE
185
+ - lib/generators/active_node/model/model_generator.rb
186
+ - lib/generators/active_node/model/templates/model.rb.erb
183
187
  - spec/functional/associations_spec.rb
184
188
  - spec/functional/base_spec.rb
185
189
  - spec/functional/graph/query_methods_spec.rb