Module: ActiveCypher::Associations

Extended by:
ActiveSupport::Concern
Defined in:
lib/active_cypher/associations.rb,
lib/active_cypher/associations/collection_proxy.rb

Overview

Note:

Because every DSL wants to be ActiveRecord when it grows up.

Module to handle association definitions (has_many, belongs_to, etc.) for ActiveCypher models.

Defined Under Namespace

Classes: CollectionProxy

Class Method Summary collapse

Class Method Details

.cyrel_direction(direction) ⇒ Symbol

Map a logical association direction to a Cyrel relationship direction.

Parameters:

  • direction (:in, :out, :both)

Returns:

  • (Symbol)

    the corresponding Cyrel::Direction value



19
20
21
22
23
24
25
26
# File 'lib/active_cypher/associations.rb', line 19

def self.cyrel_direction(direction)
  case direction
  when :out then Cyrel::Direction::OUT
  when :in then Cyrel::Direction::IN
  when :both then Cyrel::Direction::BOTH
  else raise AssociationError, "Invalid direction: #{direction}"
  end
end

.match_endpoints(start_node, start_alias, end_node, end_alias) ⇒ Cyrel::Query

Build a query matching two nodes pinned by their internal ids, ready to chain a further .match/.create/.delete_ onto. Cyrel orders clauses canonically, so the trailing operation may be appended in any order.

Parameters:

  • start_node

    the model instance at the “from” end

  • start_alias (Symbol)

    alias for the start node

  • end_node

    the model instance at the “to” end

  • end_alias (Symbol)

    alias for the end node

Returns:



57
58
59
60
61
62
63
# File 'lib/active_cypher/associations.rb', line 57

def self.match_endpoints(start_node, start_alias, end_node, end_alias)
  Cyrel::Query.new
              .match(node_pattern(start_node.class, start_alias))
              .match(node_pattern(end_node.class, end_alias))
              .where(Cyrel.node_id(start_alias).eq(start_node.internal_id))
              .where(Cyrel.node_id(end_alias).eq(end_node.internal_id))
end

.node_pattern(model_class, alias_name) ⇒ Cyrel::Pattern::Node

A labelled node pattern pinned to a model class.

Parameters:

  • model_class (Class)

    the node model class

  • alias_name (Symbol)

    the pattern alias

Returns:



32
33
34
# File 'lib/active_cypher/associations.rb', line 32

def self.node_pattern(model_class, alias_name)
  Cyrel::Pattern::Node.new(alias_name, labels: model_class.label_name)
end

.ordered_endpoints(receiver, other, direction) ⇒ Array

Order a pair of endpoints by association direction.

Parameters:

  • receiver

    the model instance owning the association

  • other

    the associated model instance

  • direction (:in, :out, :both)

    direction relative to the receiver

Returns:

  • (Array)
    start_node, end_node


70
71
72
73
74
75
76
# File 'lib/active_cypher/associations.rb', line 70

def self.ordered_endpoints(receiver, other, direction)
  case direction
  when :out, :both then [receiver, other]
  when :in then [other, receiver]
  else raise ArgumentError, "Direction '#{direction}' not supported for this operation"
  end
end

.relationship_path(start_node, end_node, direction, rel_type, rel_alias: nil) ⇒ Cyrel::Pattern::Path

Build a (start)-->(end) path between two node patterns.

Parameters:

  • start_node (Cyrel::Pattern::Node)

    the “from” node pattern

  • end_node (Cyrel::Pattern::Node)

    the “to” node pattern

  • direction (:in, :out, :both)

    direction relative to start_node

  • rel_type (String, Symbol)

    the relationship type

  • rel_alias (Symbol, nil) (defaults to: nil)

    optional alias for the relationship

Returns:



43
44
45
46
47
# File 'lib/active_cypher/associations.rb', line 43

def self.relationship_path(start_node, end_node, direction, rel_type, rel_alias: nil)
  rel = Cyrel::Pattern::Relationship.new(alias_name: rel_alias, types: rel_type,
                                         direction: cyrel_direction(direction))
  Cyrel::Pattern::Path.new([start_node, rel, end_node])
end