module Neo4j::ActiveNode::HasN

Public Instance Methods

active_rel_corresponding_rel(active_rel, direction, target_class) click to toggle source
    # File lib/neo4j/active_node/has_n.rb
255 def active_rel_corresponding_rel(active_rel, direction, target_class)
256   self.class.associations.find do |_key, assoc|
257     assoc.relationship_class_name == active_rel.class.name ||
258       (assoc.relationship_type == active_rel.type.to_sym && assoc.target_class == target_class && assoc.direction == direction)
259   end
260 end
association_proxy(name, options = {}) click to toggle source
    # File lib/neo4j/active_node/has_n.rb
212 def association_proxy(name, options = {})
213   name = name.to_sym
214   hash = association_proxy_hash(name, options)
215   association_proxy_cache_fetch(hash) do
216     if result_cache = self.instance_variable_get('@source_proxy_result_cache')
217       cache = nil
218       result_cache.inject(nil) do |proxy_to_return, object|
219         proxy = fresh_association_proxy(name, options.merge(start_object: object),
220                                         proc { (cache ||= previous_proxy_results_by_previous_id(result_cache, name))[object.neo_id] })
221 
222         object.association_proxy_cache[hash] = proxy
223 
224         (self == object ? proxy : proxy_to_return)
225       end
226     else
227       fresh_association_proxy(name, options)
228     end
229   end
230 end
association_proxy_cache() click to toggle source

Returns the current AssociationProxy cache for the association cache. It is in the format { :association_name => AssociationProxy} This is so that we

  • don't need to re-build the QueryProxy objects

  • also because the QueryProxy object caches it's results

  • so we don't need to query again

  • so that we can cache results from association calls or eager loading

    # File lib/neo4j/active_node/has_n.rb
193 def association_proxy_cache
194   @association_proxy_cache ||= {}
195 end
association_proxy_cache_fetch(key) { || ... } click to toggle source
    # File lib/neo4j/active_node/has_n.rb
197 def association_proxy_cache_fetch(key)
198   association_proxy_cache.fetch(key) do
199     value = yield
200     association_proxy_cache[key] = value
201   end
202 end
association_proxy_hash(name, options = {}) click to toggle source
    # File lib/neo4j/active_node/has_n.rb
208 def association_proxy_hash(name, options = {})
209   [name.to_sym, options.values_at(:node, :rel, :labels, :rel_length)].hash
210 end
association_query_proxy(name, options = {}) click to toggle source
    # File lib/neo4j/active_node/has_n.rb
204 def association_query_proxy(name, options = {})
205   self.class.send(:association_query_proxy, name, {start_object: self}.merge!(options))
206 end
reverse_association(association) click to toggle source
    # File lib/neo4j/active_node/has_n.rb
238 def reverse_association(association)
239   reverse_assoc = self.class.associations.find do |_key, assoc|
240     association.inverse_of?(assoc) || assoc.inverse_of?(association)
241   end
242   reverse_assoc && reverse_assoc.last
243 end
validate_has_one_rel!(rel, other_node) click to toggle source
    # File lib/neo4j/active_node/has_n.rb
250 def validate_has_one_rel!(rel, other_node)
251   raise_error = (node = send(rel.name.to_s)) && node != other_node
252   fail(HasOneConstraintError, "node #{self.class}##{neo_id} has a has_one relationship with #{other_node.class}##{other_node.neo_id}") if raise_error
253 end
validate_reverse_has_one_active_rel(active_rel, direction, other_node) click to toggle source
    # File lib/neo4j/active_node/has_n.rb
245 def validate_reverse_has_one_active_rel(active_rel, direction, other_node)
246   rel = active_rel_corresponding_rel(active_rel, direction, other_node.class)
247   validate_has_one_rel!(rel.last, other_node) if rel && rel.last.type == :has_one
248 end
validate_reverse_has_one_core_rel(association, other_node) click to toggle source
    # File lib/neo4j/active_node/has_n.rb
232 def validate_reverse_has_one_core_rel(association, other_node)
233   return unless Neo4j::Config[:enforce_has_one]
234   reverse_assoc = reverse_association(association)
235   validate_has_one_rel!(reverse_assoc, other_node) if reverse_assoc && reverse_assoc.type == :has_one
236 end

Private Instance Methods

fresh_association_proxy(name, options = {}, result_cache_proc = nil) click to toggle source
    # File lib/neo4j/active_node/has_n.rb
264 def fresh_association_proxy(name, options = {}, result_cache_proc = nil)
265   AssociationProxy.new(association_query_proxy(name, options), deferred_nodes_for_association(name), result_cache_proc)
266 end
previous_proxy_results_by_previous_id(result_cache, association_name) click to toggle source
    # File lib/neo4j/active_node/has_n.rb
268 def previous_proxy_results_by_previous_id(result_cache, association_name)
269   query_proxy = self.class.as(:previous).where(neo_id: result_cache.map(&:neo_id))
270   query_proxy = self.class.send(:association_query_proxy, association_name, previous_query_proxy: query_proxy, node: :next, optional: true)
271 
272   Hash[*query_proxy.pluck('ID(previous)', 'collect(next)').flatten(1)].each_value do |records|
273     records.each do |record|
274       record.instance_variable_set('@source_proxy_result_cache', records)
275     end
276   end
277 end