module Neo4j::ActiveNode::Query::QueryProxyMethods

rubocop:disable Metrics/ModuleLength

Constants

FIRST

rubocop:enable Metrics/ModuleLength

LAST

Public Instance Methods

all_rels_to(node)
Alias for: rels_to
as(node_var) click to toggle source
   # File lib/neo4j/active_node/query/query_proxy_methods.rb
20 def as(node_var)
21   new_link(node_var)
22 end
as_models(models) click to toggle source

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)
    # File lib/neo4j/active_node/query/query_proxy_methods.rb
183 def as_models(models)
184   where_clause = models.map do |model|
185     "`#{identity}`:" + model.mapped_label_names.map do |mapped_label_name|
186       "`#{mapped_label_name}`"
187     end.join(':')
188   end.join(' OR ')
189 
190   where("(#{where_clause})")
191 end
blank?(target = nil)
Alias for: empty?
count(distinct = nil, target = nil) click to toggle source

@return [Integer] number of nodes of this class

   # File lib/neo4j/active_node/query/query_proxy_methods.rb
55 def count(distinct = nil, target = nil)
56   return 0 if unpersisted_start_object?
57   fail(Neo4j::InvalidParameterError, ':count accepts the `:distinct` symbol or nil as a parameter') unless distinct.nil? || distinct == :distinct
58   query_with_target(target) do |var|
59     q = ensure_distinct(var, !distinct.nil?)
60     limited_query = self.query.clause?(:limit) ? self.query.break.with(var) : self.query.reorder
61     limited_query.pluck("count(#{q}) AS #{var}").first
62   end
63 end
distinct() click to toggle source
   # File lib/neo4j/active_node/query/query_proxy_methods.rb
44 def distinct
45   new_link.tap do |e|
46     e.instance_variable_set(:@distinct, true)
47   end
48 end
empty?(target = nil) click to toggle source
   # File lib/neo4j/active_node/query/query_proxy_methods.rb
78 def empty?(target = nil)
79   return true if unpersisted_start_object?
80   query_with_target(target) { |var| !self.exists?(nil, var) }
81 end
Also aliased as: blank?
exists?(node_condition = nil, target = nil) click to toggle source
    # File lib/neo4j/active_node/query/query_proxy_methods.rb
100 def exists?(node_condition = nil, target = nil)
101   unless [Integer, String, Hash, NilClass].any? { |c| node_condition.is_a?(c) }
102     fail(Neo4j::InvalidParameterError, ':exists? only accepts ids or conditions')
103   end
104   query_with_target(target) do |var|
105     start_q = exists_query_start(node_condition, var)
106     result = start_q.query.reorder.return("ID(#{var}) AS proof_of_life LIMIT 1").first
107     !!result
108   end
109 end
find(*args) click to toggle source

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

   # File lib/neo4j/active_node/query/query_proxy_methods.rb
26 def find(*args)
27   scoping { @model.find(*args) }
28 end
find_or_create_by(params) click to toggle source

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.

    # File lib/neo4j/active_node/query/query_proxy_methods.rb
151 def find_or_create_by(params)
152   fail 'Method invalid when called on Class objects' unless source_object
153   result = self.where(params).first
154   return result unless result.nil?
155   Neo4j::ActiveBase.run_transaction do
156     node = model.create(params)
157     self << node
158     return node
159   end
160 end
find_or_initialize_by(attributes, &block) click to toggle source
    # File lib/neo4j/active_node/query/query_proxy_methods.rb
162 def find_or_initialize_by(attributes, &block)
163   find_by(attributes) || initialize_by_current_chain_params(attributes, &block)
164 end
first(target = nil) click to toggle source
   # File lib/neo4j/active_node/query/query_proxy_methods.rb
30 def first(target = nil)
31   first_and_last(FIRST, target)
32 end
first_or_initialize(attributes = {}, &block) click to toggle source
    # File lib/neo4j/active_node/query/query_proxy_methods.rb
166 def first_or_initialize(attributes = {}, &block)
167   first || initialize_by_current_chain_params(attributes, &block)
168 end
first_rel_to(node) click to toggle source

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) = #{other_node.neo_id} RETURN r` @param [#neo_id, String, Enumerable] node An object to be sent to `match_to`. See params for that method. @return A relationship (ActiveRel, CypherRelationship, EmbeddedRelationship) or nil.

    # File lib/neo4j/active_node/query/query_proxy_methods.rb
137 def first_rel_to(node)
138   self.match_to(node).limit(1).pluck(rel_var).first
139 end
having_rel(association_name, rel_properties = {}) click to toggle source

Matches all nodes having at least a relation

@example Load all people having a friend

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

@example Load all people having a best friend

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

@return [QueryProxy] A new QueryProxy

    # File lib/neo4j/active_node/query/query_proxy_methods.rb
202 def having_rel(association_name, rel_properties = {})
203   association = association_or_fail(association_name)
204   where("(#{identity})#{association.arrow_cypher(nil, rel_properties)}()")
205 end
include?(other, target = nil) click to toggle source

@param [Neo4j::ActiveNode, Neo4j::Node, String] other An instance of a Neo4j.rb model, a Neo4j-core node, or a string uuid @param [String, Symbol] target An identifier of a link in the Cypher chain @return [Boolean]

   # File lib/neo4j/active_node/query/query_proxy_methods.rb
88 def include?(other, target = nil)
89   query_with_target(target) do |var|
90     where_filter = if other.respond_to?(:neo_id) || association_id_key == :neo_id
91                      "ID(#{var}) = {other_node_id}"
92                    else
93                      "#{var}.#{association_id_key} = {other_node_id}"
94                    end
95     node_id = other.respond_to?(:neo_id) ? other.neo_id : other
96     self.where(where_filter).params(other_node_id: node_id).query.reorder.return("count(#{var}) as count").first.count > 0
97   end
98 end
last(target = nil) click to toggle source
   # File lib/neo4j/active_node/query/query_proxy_methods.rb
34 def last(target = nil)
35   first_and_last(LAST, target)
36 end
limit_value() click to toggle source

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

   # File lib/neo4j/active_node/query/query_proxy_methods.rb
72 def limit_value
73   return unless self.query.clause?(:limit)
74   limit_clause = self.query.send(:clauses).find { |clause| clause.is_a?(Neo4j::Core::QueryClauses::LimitClause) }
75   limit_clause.instance_variable_get(:@arg)
76 end
match_to(node) click to toggle source

Shorthand for `MATCH (start)--(other_node) WHERE ID(other_node) = #{other_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. @param [#neo_id, String, Enumerable] node A node, a string representing a node's ID, or an enumerable of nodes or IDs. @return [Neo4j::ActiveNode::Query::QueryProxy] A QueryProxy object upon which you can build.

    # File lib/neo4j/active_node/query/query_proxy_methods.rb
118 def match_to(node)
119   first_node = node.is_a?(Array) ? node.first : node
120   where_arg = if first_node.respond_to?(:neo_id)
121                 {neo_id: node.is_a?(Array) ? node.map(&:neo_id) : node}
122               elsif !node.nil?
123                 {association_id_key => node.is_a?(Array) ? ids_array(node) : node}
124               else
125                 # support for null object pattern
126                 '1 = 2'
127               end
128 
129   self.where(where_arg)
130 end
not_having_rel(association_name, rel_properties = {}) click to toggle source

Matches all nodes not having a certain relation

@example Load all people not having friends

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

@example Load all people not having best friends

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

@return [QueryProxy] A new QueryProxy

    # File lib/neo4j/active_node/query/query_proxy_methods.rb
216 def not_having_rel(association_name, rel_properties = {})
217   association = association_or_fail(association_name)
218   where_not("(#{identity})#{association.arrow_cypher(nil, rel_properties)}()")
219 end
optional(association, node_var = nil, rel_var = nil) click to toggle source

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

    # File lib/neo4j/active_node/query/query_proxy_methods.rb
171 def optional(association, node_var = nil, rel_var = nil)
172   self.send(association, node_var, rel_var, optional: true)
173 end
order_property() click to toggle source
   # File lib/neo4j/active_node/query/query_proxy_methods.rb
38 def order_property
39   # This should maybe be based on a setting in the association
40   # rather than a hardcoded `nil`
41   model ? model.id_property_name : nil
42 end
propagate_context(query_proxy) click to toggle source
   # File lib/neo4j/active_node/query/query_proxy_methods.rb
50 def propagate_context(query_proxy)
51   query_proxy.instance_variable_set(:@distinct, @distinct)
52 end
rel() click to toggle source
   # File lib/neo4j/active_node/query/query_proxy_methods.rb
16 def rel
17   rels.first
18 end
rels() click to toggle source
   # File lib/neo4j/active_node/query/query_proxy_methods.rb
10 def rels
11   fail 'Cannot get rels without a relationship variable.' if !@rel_var
12 
13   pluck(@rel_var)
14 end
rels_to(node) click to toggle source

Returns all relationships across a QueryProxy chain between a given node or array of nodes and the preceeding link. @param [#neo_id, String, Enumerable] node An object to be sent to `match_to`. See params for that method. @return An enumerable of relationship objects.

    # File lib/neo4j/active_node/query/query_proxy_methods.rb
144 def rels_to(node)
145   self.match_to(node).pluck(rel_var)
146 end
Also aliased as: all_rels_to
size() click to toggle source
   # File lib/neo4j/active_node/query/query_proxy_methods.rb
65 def size
66   result_cache? ? result_cache_for.length : count
67 end

Private Instance Methods

association_id_key() click to toggle source

@return [String] The primary key of a the current QueryProxy's model or target class

    # File lib/neo4j/active_node/query/query_proxy_methods.rb
273 def association_id_key
274   self.association.nil? ? model.primary_key : self.association.target_class.primary_key
275 end
association_or_fail(association_name) click to toggle source
    # File lib/neo4j/active_node/query/query_proxy_methods.rb
223 def association_or_fail(association_name)
224   model.associations[association_name] || fail(ArgumentError, "No such association #{association_name}")
225 end
exists_query_start(condition, target) click to toggle source
    # File lib/neo4j/active_node/query/query_proxy_methods.rb
287 def exists_query_start(condition, target)
288   case condition
289   when Integer
290     self.where("ID(#{target}) = {exists_condition}").params(exists_condition: condition)
291   when Hash
292     self.where(condition.keys.first => condition.values.first)
293   when String
294     self.where(model.primary_key => condition)
295   else
296     self
297   end
298 end
find_inverse_association!(model, source, association) click to toggle source
    # File lib/neo4j/active_node/query/query_proxy_methods.rb
227 def find_inverse_association!(model, source, association)
228   model.associations.values.find do |reverse_association|
229     association.inverse_of?(reverse_association) ||
230       reverse_association.inverse_of?(association) ||
231       inverse_relation_of?(source, association, model, reverse_association)
232   end || fail("Could not find reverse association for #{@context}")
233 end
first_and_last(func, target) click to toggle source
    # File lib/neo4j/active_node/query/query_proxy_methods.rb
257 def first_and_last(func, target)
258   new_query, pluck_proc = if self.query.clause?(:order)
259                             [self.query.with(identity),
260                              proc { |var| "#{func}(COLLECT(#{var})) as #{var}" }]
261                           else
262                             ord_prop = (func == LAST ? {order_property => :DESC} : order_property)
263                             [self.order(ord_prop).limit(1),
264                              proc { |var| var }]
265                           end
266   query_with_target(target) do |var|
267     final_pluck = pluck_proc.call(var)
268     new_query.pluck(final_pluck)
269   end.first
270 end
ids_array(node) click to toggle source

@param [Enumerable] node An enumerable of nodes or ids. @return [Array] An array after having `id` called on each object

    # File lib/neo4j/active_node/query/query_proxy_methods.rb
279 def ids_array(node)
280   node.first.respond_to?(:id) ? node.map(&:id) : node
281 end
initialize_by_current_chain_params(params = {}) { |m| ... } click to toggle source
    # File lib/neo4j/active_node/query/query_proxy_methods.rb
242 def initialize_by_current_chain_params(params = {})
243   result = new(where_clause_params.merge(params))
244 
245   inverse_association = find_inverse_association!(model, source_object.class, association) if source_object
246   result.tap do |m|
247     yield(m) if block_given?
248     m.public_send(inverse_association.name) << source_object if inverse_association
249   end
250 end
inverse_relation_of?(source, source_association, target, target_association) click to toggle source
    # File lib/neo4j/active_node/query/query_proxy_methods.rb
235 def inverse_relation_of?(source, source_association, target, target_association)
236   source_association.direction != target_association.direction &&
237     source == target_association.target_class &&
238     target == source_association.target_class &&
239     source_association.relationship_class_name == target_association.relationship_class_name
240 end
query_with_target(target) { |target || identity| ... } click to toggle source
    # File lib/neo4j/active_node/query/query_proxy_methods.rb
283 def query_with_target(target)
284   yield(target || identity)
285 end
where_clause_params() click to toggle source
    # File lib/neo4j/active_node/query/query_proxy_methods.rb
252 def where_clause_params
253   query.clauses.select { |c| c.is_a?(Neo4j::Core::QueryClauses::WhereClause) && c.arg.is_a?(Hash) }
254        .map! { |e| e.arg[identity] }.compact.inject { |a, b| a.merge(b) } || {}
255 end