Module: Neo4j::ActiveNode::Query::QueryProxyMethods

Included in:
QueryProxy
Defined in:
lib/neo4j/active_node/query/query_proxy_methods.rb

Overview

rubocop:disable Metrics/ModuleLength

Constant Summary collapse

FIRST =

rubocop:enable Metrics/ModuleLength

'HEAD'
LAST =
'LAST'

Instance Method Summary collapse

Instance Method Details

#as(node_var) ⇒ Object


20
21
22
# File 'lib/neo4j/active_node/query/query_proxy_methods.rb', line 20

def as(node_var)
  new_link(node_var)
end

#as_models(models) ⇒ Object

Takes an Array of ActiveNode models and applies the appropriate WHERE clause So for a `Teacher` model inheriting from a `Person` model and an `Article` model if you called .as_models([Teacher, Article]) The where clause would look something like:

.. code-block

cypher

WHERE (node_var:Teacher:Person OR node_var:Article)

183
184
185
186
187
188
189
190
191
# File 'lib/neo4j/active_node/query/query_proxy_methods.rb', line 183

def as_models(models)
  where_clause = models.map do |model|
    "`#{identity}`:" + model.mapped_label_names.map do |mapped_label_name|
      "`#{mapped_label_name}`"
    end.join(':')
  end.join(' OR ')

  where("(#{where_clause})")
end

#count(distinct = nil, target = nil) ⇒ Integer

Returns number of nodes of this class.

Returns:

  • (Integer)

    number of nodes of this class


55
56
57
58
59
60
61
62
63
# File 'lib/neo4j/active_node/query/query_proxy_methods.rb', line 55

def count(distinct = nil, target = nil)
  return 0 if unpersisted_start_object?
  fail(Neo4j::InvalidParameterError, ':count accepts the `:distinct` symbol or nil as a parameter') unless distinct.nil? || distinct == :distinct
  query_with_target(target) do |var|
    q = ensure_distinct(var, !distinct.nil?)
    limited_query = self.query.clause?(:limit) ? self.query.break.with(var) : self.query.reorder
    limited_query.pluck("count(#{q}) AS #{var}").first
  end
end

#distinctObject


44
45
46
47
48
# File 'lib/neo4j/active_node/query/query_proxy_methods.rb', line 44

def distinct
  new_link.tap do |e|
    e.instance_variable_set(:@distinct, true)
  end
end

#empty?(target = nil) ⇒ Boolean Also known as: blank?

Returns:


78
79
80
81
# File 'lib/neo4j/active_node/query/query_proxy_methods.rb', line 78

def empty?(target = nil)
  return true if unpersisted_start_object?
  query_with_target(target) { |var| !self.exists?(nil, var) }
end

#exists?(node_condition = nil, target = nil) ⇒ Boolean

Returns:


100
101
102
103
104
105
106
107
108
109
# File 'lib/neo4j/active_node/query/query_proxy_methods.rb', line 100

def exists?(node_condition = nil, target = nil)
  unless [Integer, String, Hash, NilClass].any? { |c| node_condition.is_a?(c) }
    fail(Neo4j::InvalidParameterError, ':exists? only accepts ids or conditions')
  end
  query_with_target(target) do |var|
    start_q = exists_query_start(node_condition, var)
    result = start_q.query.reorder.return("ID(#{var}) AS proof_of_life LIMIT 1").first
    !!result
  end
end

#find(*args) ⇒ Object

Give ability to call `#find` on associations to get a scoped find Doesn't pass through via `method_missing` because Enumerable has a `#find` method


26
27
28
# File 'lib/neo4j/active_node/query/query_proxy_methods.rb', line 26

def find(*args)
  scoping { @model.find(*args) }
end

#find_or_create_by(params) ⇒ Object

When called, this method returns a single node that satisfies the match specified in the params hash. If no existing node is found to satisfy the match, one is created or associated as expected.


151
152
153
154
155
156
157
158
159
160
# File 'lib/neo4j/active_node/query/query_proxy_methods.rb', line 151

def find_or_create_by(params)
  fail 'Method invalid when called on Class objects' unless source_object
  result = self.where(params).first
  return result unless result.nil?
  Neo4j::ActiveBase.run_transaction do
    node = model.create(params)
    self << node
    return node
  end
end

#find_or_initialize_by(attributes, &block) ⇒ Object


162
163
164
# File 'lib/neo4j/active_node/query/query_proxy_methods.rb', line 162

def find_or_initialize_by(attributes, &block)
  find_by(attributes) || initialize_by_current_chain_params(attributes, &block)
end

#first(target = nil) ⇒ Object


30
31
32
# File 'lib/neo4j/active_node/query/query_proxy_methods.rb', line 30

def first(target = nil)
  first_and_last(FIRST, target)
end

#first_or_initialize(attributes = {}, &block) ⇒ Object


166
167
168
# File 'lib/neo4j/active_node/query/query_proxy_methods.rb', line 166

def first_or_initialize(attributes = {}, &block)
  first || initialize_by_current_chain_params(attributes, &block)
end

#first_rel_to(node) ⇒ Object

Gives you the first relationship between the last link of a QueryProxy chain and a given node Shorthand for `MATCH (start)--(other_node) WHERE ID(other_node) = #Neo4j::ActiveNode::Query::QueryProxyMethods.other_nodeother_node.neo_id RETURN r`

Parameters:

  • node (#neo_id, String, Enumerable)

    An object to be sent to `match_to`. See params for that method.

Returns:

  • A relationship (ActiveRel, CypherRelationship, EmbeddedRelationship) or nil.


137
138
139
# File 'lib/neo4j/active_node/query/query_proxy_methods.rb', line 137

def first_rel_to(node)
  self.match_to(node).limit(1).pluck(rel_var).first
end

#having_rel(association_name, rel_properties = {}) ⇒ QueryProxy

Matches all nodes having at least a relation

Examples:

Load all people having a friend

Person.all.having_rel(:friends).to_a # => Returns a list of `Person`

Load all people having a best friend

Person.all.having_rel(:friends, best: true).to_a # => Returns a list of `Person`

Returns:


202
203
204
205
# File 'lib/neo4j/active_node/query/query_proxy_methods.rb', line 202

def having_rel(association_name, rel_properties = {})
  association = association_or_fail(association_name)
  where("(#{identity})#{association.arrow_cypher(nil, rel_properties)}()")
end

#include?(other, target = nil) ⇒ Boolean

Parameters:

  • other (Neo4j::ActiveNode, Neo4j::Node, String)

    An instance of a Neo4j.rb model, a Neo4j-core node, or a string uuid

  • target (String, Symbol) (defaults to: nil)

    An identifier of a link in the Cypher chain

Returns:


88
89
90
91
92
93
94
95
96
97
98
# File 'lib/neo4j/active_node/query/query_proxy_methods.rb', line 88

def include?(other, target = nil)
  query_with_target(target) do |var|
    where_filter = if other.respond_to?(:neo_id) || association_id_key == :neo_id
                     "ID(#{var}) = {other_node_id}"
                   else
                     "#{var}.#{association_id_key} = {other_node_id}"
                   end
    node_id = other.respond_to?(:neo_id) ? other.neo_id : other
    self.where(where_filter).params(other_node_id: node_id).query.reorder.return("count(#{var}) as count").first.count > 0
  end
end

#last(target = nil) ⇒ Object


34
35
36
# File 'lib/neo4j/active_node/query/query_proxy_methods.rb', line 34

def last(target = nil)
  first_and_last(LAST, target)
end

#limit_valueObject

TODO: update this with public API methods if/when they are exposed


72
73
74
75
76
# File 'lib/neo4j/active_node/query/query_proxy_methods.rb', line 72

def limit_value
  return unless self.query.clause?(:limit)
  limit_clause = self.query.send(:clauses).find { |clause| clause.is_a?(Neo4j::Core::QueryClauses::LimitClause) }
  limit_clause.instance_variable_get(:@arg)
end

#match_to(node) ⇒ Neo4j::ActiveNode::Query::QueryProxy

Shorthand for `MATCH (start)--(other_node) WHERE ID(other_node) = #Neo4j::ActiveNode::Query::QueryProxyMethods.other_nodeother_node.neo_id` The `node` param can be a persisted ActiveNode instance, any string or integer, or nil. When it's a node, it'll use the object's neo_id, which is fastest. When not nil, it'll figure out the primary key of that model. When nil, it uses `1 = 2` to prevent matching all records, which is the default behavior when nil is passed to `where` in QueryProxy.

Parameters:

  • node (#neo_id, String, Enumerable)

    A node, a string representing a node's ID, or an enumerable of nodes or IDs.

Returns:


118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/neo4j/active_node/query/query_proxy_methods.rb', line 118

def match_to(node)
  first_node = node.is_a?(Array) ? node.first : node
  where_arg = if first_node.respond_to?(:neo_id)
                {neo_id: node.is_a?(Array) ? node.map(&:neo_id) : node}
              elsif !node.nil?
                {association_id_key => node.is_a?(Array) ? ids_array(node) : node}
              else
                # support for null object pattern
                '1 = 2'
              end

  self.where(where_arg)
end

#not_having_rel(association_name, rel_properties = {}) ⇒ QueryProxy

Matches all nodes not having a certain relation

Examples:

Load all people not having friends

Person.all.not_having_rel(:friends).to_a # => Returns a list of `Person`

Load all people not having best friends

Person.all.not_having_rel(:friends, best: true).to_a # => Returns a list of `Person`

Returns:


216
217
218
219
# File 'lib/neo4j/active_node/query/query_proxy_methods.rb', line 216

def not_having_rel(association_name, rel_properties = {})
  association = association_or_fail(association_name)
  where_not("(#{identity})#{association.arrow_cypher(nil, rel_properties)}()")
end

#optional(association, node_var = nil, rel_var = nil) ⇒ Object

A shortcut for attaching a new, optional match to the end of a QueryProxy chain.


171
172
173
# File 'lib/neo4j/active_node/query/query_proxy_methods.rb', line 171

def optional(association, node_var = nil, rel_var = nil)
  self.send(association, node_var, rel_var, optional: true)
end

#order_propertyObject


38
39
40
41
42
# File 'lib/neo4j/active_node/query/query_proxy_methods.rb', line 38

def order_property
  # This should maybe be based on a setting in the association
  # rather than a hardcoded `nil`
  model ? model.id_property_name : nil
end

#propagate_context(query_proxy) ⇒ Object


50
51
52
# File 'lib/neo4j/active_node/query/query_proxy_methods.rb', line 50

def propagate_context(query_proxy)
  query_proxy.instance_variable_set(:@distinct, @distinct)
end

#relObject


16
17
18
# File 'lib/neo4j/active_node/query/query_proxy_methods.rb', line 16

def rel
  rels.first
end

#relsObject


10
11
12
13
14
# File 'lib/neo4j/active_node/query/query_proxy_methods.rb', line 10

def rels
  fail 'Cannot get rels without a relationship variable.' if !@rel_var

  pluck(@rel_var)
end

#rels_to(node) ⇒ Object Also known as: all_rels_to

Returns all relationships across a QueryProxy chain between a given node or array of nodes and the preceeding link.

Parameters:

  • node (#neo_id, String, Enumerable)

    An object to be sent to `match_to`. See params for that method.

Returns:

  • An enumerable of relationship objects.


144
145
146
# File 'lib/neo4j/active_node/query/query_proxy_methods.rb', line 144

def rels_to(node)
  self.match_to(node).pluck(rel_var)
end

#sizeObject


65
66
67
# File 'lib/neo4j/active_node/query/query_proxy_methods.rb', line 65

def size
  result_cache? ? result_cache_for.length : count
end