Class: Neo4j::Wrapper::HasN::DeclRel

Inherits:
Object
  • Object
show all
Defined in:
lib/neo4j-wrapper/has_n/decl_rel.rb

Overview

A DSL for declared relationships has_n and has_one This DSL will be used to create accessor methods for relationships. Instead of using the ‘raw’ Neo4j::NodeMixin#rels method where one needs to know the name of relationship and direction one can use the generated accessor methods.

The DSL can also be used to specify a mapping to a Ruby class for a relationship, see Neo4j::HasN::DeclRelationshipDsl#relationship

The following methods will be generated:

Folder#files

returns an Enumerable of outgoing nodes for relationship ‘files’

Folder#files_rels

returns an Enumerable of outgoing relationships for relationship ‘files’

File#folder

for adding one node for the relationship ‘files’ from the outgoing Folder node

File#folder_rel

for accessing relationship ‘files’ from the outgoing Folder node

File#folder

for accessing nodes from relationship ‘files’ from the outgoing Folder node

Examples:


class Folder
   include Neo4j::NodeMixin
   property :name
   # Declaring a Many relationship to any other node
   has_n(:files)
 end

class File
  include Neo4j::NodeMixin
  # declaring a incoming relationship from Folder's relationship files
  has_one(:folder).from(Folder, :files)
end

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(method_id, has_one, target_class) ⇒ DeclRel

Returns a new instance of DeclRel.



38
39
40
41
42
43
44
45
# File 'lib/neo4j-wrapper/has_n/decl_rel.rb', line 38

def initialize(method_id, has_one, target_class)
  @method_id = method_id
  @has_one = has_one
  @target_class = target_class
  @dir = :outgoing
  @rel_type = method_id.to_s
  @source_class = target_class
end

Instance Attribute Details

#dirObject (readonly)

Returns the value of attribute dir.



36
37
38
# File 'lib/neo4j-wrapper/has_n/decl_rel.rb', line 36

def dir
  @dir
end

#rel_typeObject (readonly)

Returns the value of attribute rel_type.



36
37
38
# File 'lib/neo4j-wrapper/has_n/decl_rel.rb', line 36

def rel_type
  @rel_type
end

#source_classObject (readonly)

Returns the value of attribute source_class.



36
37
38
# File 'lib/neo4j-wrapper/has_n/decl_rel.rb', line 36

def source_class
  @source_class
end

#target_classObject (readonly)

Returns the value of attribute target_class.



36
37
38
# File 'lib/neo4j-wrapper/has_n/decl_rel.rb', line 36

def target_class
  @target_class
end

Instance Method Details

#_all_relationships(node) ⇒ Object



238
239
240
# File 'lib/neo4j-wrapper/has_n/decl_rel.rb', line 238

def _all_relationships(node) #:nodoc:
  node._rels(dir, rel_type)
end

#_each_node(node, &block) ⇒ Object



220
221
222
223
224
# File 'lib/neo4j-wrapper/has_n/decl_rel.rb', line 220

def _each_node(node, &block) #:nodoc:
  node._rels(dir, rel_type).each do |rel|
    block.call rel._other_node(node)
  end
end

#all_relationships(node) ⇒ Object



243
244
245
# File 'lib/neo4j-wrapper/has_n/decl_rel.rb', line 243

def all_relationships(node)
  node.rels(dir, rel_type)
end

#create_relationship_to(node, other) ⇒ Object



248
249
250
251
252
253
254
255
256
# File 'lib/neo4j-wrapper/has_n/decl_rel.rb', line 248

def create_relationship_to(node, other) # :nodoc:
  from, to = incoming? ? [other, node] : [node, other]

  if relationship_class
    relationship_class.new(@rel_type, from._java_node, to._java_node)
  else
    Neo4j::Relationship.new(@rel_type, from, to)
  end
end

#each_node(node, &block) ⇒ Object



213
214
215
216
217
# File 'lib/neo4j-wrapper/has_n/decl_rel.rb', line 213

def each_node(node, &block)
  node.rels(dir, rel_type).each do |rel|
    block.call(rel.other_node(node))
  end
end

#from(*args) ⇒ Object

Specifies an incoming relationship. Will use the outgoing relationship given by the from class.

Examples:

with prefix FileNode

class FolderNode
  include Neo4j::NodeMixin
  has_n(:files).to(FileNode)
end

class FileNode
  include Neo4j::NodeMixin
  # will only traverse any incoming relationship of type files from node FileNode
  has_one(:folder).from(FolderNode, :files)
end

file = FileNode.new
# create an outgoing relationship of type 'FileNode#files' from folder node to file (FileNode is the prefix).
file.folder = FolderNode.new

without prefix


class FolderNode
  include Neo4j::NodeMixin
  has_n(:files)
end

class FileNode
  include Neo4j::NodeMixin
  has_one(:folder).from(:files)  # will traverse any incoming relationship of type files
end

file = FileNode.new
# create an outgoing relationship of type 'files' from folder node to file
file.folder = FolderNode.new


156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/neo4j-wrapper/has_n/decl_rel.rb', line 156

def from(*args)
  @dir = :incoming

  if args.size > 1
    # handle specified (prefixed) relationship, e.g. has_n(:known_by).from(clazz, :type)
    @target_class = args[0]
    @rel_type = "#{@target_class}##{args[1]}"
    @relationship_name = args[1].to_sym
  elsif Symbol === args[0]
    # handle unspecified (unprefixed) relationship, e.g. has_n(:known_by).from(:type)
    @rel_type = args[0].to_s
  else
    raise "Expected a symbol for, got #{args[0]}"
  end
  self
end

#has_n?true, false

Returns:

  • (true, false)


68
69
70
# File 'lib/neo4j-wrapper/has_n/decl_rel.rb', line 68

def has_n?
  !@has_one
end

#has_one?true, false

Returns:

  • (true, false)


63
64
65
# File 'lib/neo4j-wrapper/has_n/decl_rel.rb', line 63

def has_one?
  @has_one
end

#incoming?true, false

Returns:

  • (true, false)


73
74
75
# File 'lib/neo4j-wrapper/has_n/decl_rel.rb', line 73

def incoming? #:nodoc:
  @dir == :incoming
end

#inherit_newObject



47
48
49
50
51
52
53
54
55
56
# File 'lib/neo4j-wrapper/has_n/decl_rel.rb', line 47

def inherit_new
  base = self
  dr = DeclRel.new(@method_id, @has_one, @target_class)
  dr.instance_eval do
    @dir = base.dir
    @rel_type = base.rel_type
    @source_class = base.source_class
  end
  dr
end

#relationship(rel_class) ⇒ Object

Specifies which relationship ruby class to use for the relationship

order = Order.new
order.products << Product.new
order.products_rels.first # => OrderLine

Examples:


class OrderLine
  include Neo4j::RelationshipMixin
  property :units
  property :unit_price
end

class Order
  property :total_cost
  property :dispatched
  has_n(:products).to(Product).relationship(OrderLine)
end


193
194
195
196
# File 'lib/neo4j-wrapper/has_n/decl_rel.rb', line 193

def relationship(rel_class)
  @relationship = rel_class
  self
end

#relationship_classObject



200
201
202
203
204
205
206
207
208
209
210
# File 'lib/neo4j-wrapper/has_n/decl_rel.rb', line 200

def relationship_class # :nodoc:
  if !@relationship_name.nil? && @relationship.nil?
    other_class_dsl = @target_class._decl_rels[@relationship_name]
    if other_class_dsl
      @relationship = other_class_dsl.relationship_class
    else
      Neo4j.logger.warn "Unknown outgoing relationship #{@relationship_name} on #{@target_class}"
    end
  end
  @relationship
end

#single_node(node) ⇒ Object



227
228
229
230
# File 'lib/neo4j-wrapper/has_n/decl_rel.rb', line 227

def single_node(node)
  rel = single_relationship(node)
  rel && rel.other_node(node)
end

#single_relationship(node) ⇒ Object



233
234
235
# File 'lib/neo4j-wrapper/has_n/decl_rel.rb', line 233

def single_relationship(node) #:nodoc:
  node.rel(dir, rel_type)
end

#to(target) ⇒ Object

Specifies an outgoing relationship. The name of the outgoing class will be used as a prefix for the relationship used.

folder = FolderNode.new
# generate a relationship between folder and file of type 'FileNode#files'
folder.files << FileNode.new

Examples:

Example

class FolderNode
  include Neo4j::NodeMixin
  has_n(:files).to(FileNode)
end

without prefix


class FolderNode
  include Neo4j::NodeMixin
  has_n(:files).to(:contains)
end

file = FileNode.new
# create an outgoing relationship of type 'contains' from folder node to file
folder.files << FolderNode.new

Parameters:

  • target (Class)

    the other class to which this relationship goes

Returns:

  • self



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/neo4j-wrapper/has_n/decl_rel.rb', line 104

def to(target)
  @dir = :outgoing

  if Class === target
    # handle e.g. has_n(:friends).to(class)
    @target_class = target
    @rel_type = "#{@source_class}##{@method_id}"
  elsif Symbol === target
    # handle e.g. has_n(:friends).to(:knows)
    @rel_type = target.to_s
  else
    raise "Expected a class or a symbol for, got #{target}/#{target.class}"
  end
  self
end

#to_sObject



58
59
60
# File 'lib/neo4j-wrapper/has_n/decl_rel.rb', line 58

def to_s
  "DeclRel #{object_id} dir: #{@dir} rel_id: #{@method_id}, rel_type: #{@rel_type}, target_class:#{@target_class} rel_class:#{@relationship}"
end