active_node 2.2.6 → 2.2.7

Sign up to get free protection for your applications and to get access to all the features.
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