Class: ActiveGraph::Node::HasN::AssociationProxy

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Enumerable
Defined in:
lib/active_graph/node/has_n.rb

Overview

Return this object from associations It uses a QueryProxy to get results But also caches results and can have results cached on it

Constant Summary collapse

QUERY_PROXY_METHODS =
[:<<, :delete, :create, :pluck, :where, :where_not, :rel_where, :rel_order, :order, :skip, :limit]
CACHED_RESULT_METHODS =
[]

Instance Method Summary collapse

Constructor Details

#initialize(query_proxy, deferred_objects = [], result_cache_proc = nil) ⇒ AssociationProxy

Returns a new instance of AssociationProxy.



11
12
13
14
15
16
17
18
19
20
21
# File 'lib/active_graph/node/has_n.rb', line 11

def initialize(query_proxy, deferred_objects = [], result_cache_proc = nil)
  @query_proxy = query_proxy
  @deferred_objects = deferred_objects

  @result_cache_proc = result_cache_proc

  # Represents the thing which can be enumerated
  # default to @query_proxy, but will be set to
  # @cached_result if that is set
  @enumerable = @query_proxy
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args, **kwargs, &block) ⇒ Object



158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/active_graph/node/has_n.rb', line 158

def method_missing(method_name, *args, **kwargs, &block)
  target = target_for_missing_method(method_name)
  super if target.nil?

  cache_query_proxy_result if !cached? && !target.is_a?(ActiveGraph::Node::Query::QueryProxy)
  clear_cache_result if target.is_a?(ActiveGraph::Node::Query::QueryProxy)

  if RUBY_VERSION < '3' && kwargs.empty?
    target.public_send(method_name, *args, &block)
  else
    target.public_send(method_name, *args, **kwargs, &block)
  end
end

Instance Method Details

#+(other) ⇒ Object



72
73
74
# File 'lib/active_graph/node/has_n.rb', line 72

def +(other)
  self.to_a + other
end

#==(other) ⇒ Object



68
69
70
# File 'lib/active_graph/node/has_n.rb', line 68

def ==(other)
  self.to_a == other.to_a
end

#add_to_cache(object, rel = nil) ⇒ Object



112
113
114
115
# File 'lib/active_graph/node/has_n.rb', line 112

def add_to_cache(object, rel = nil)
  (@cached_rels ||= []) << rel if rel
  (@cached_result ||= []).tap { |results| results << object if object && !results.include?(object) }
end

#cache_query_proxy_resultObject



121
122
123
# File 'lib/active_graph/node/has_n.rb', line 121

def cache_query_proxy_result
  (result_cache_proc_cache || @query_proxy).to_a.tap { |result| cache_result(result) }
end

#cache_result(result) ⇒ Object



102
103
104
105
# File 'lib/active_graph/node/has_n.rb', line 102

def cache_result(result)
  @cached_result = result
  @enumerable = (@cached_result || @query_proxy)
end

#cached?Boolean

Returns:



133
134
135
# File 'lib/active_graph/node/has_n.rb', line 133

def cached?
  !!@cached_result
end

#clear_cache_resultObject



129
130
131
# File 'lib/active_graph/node/has_n.rb', line 129

def clear_cache_result
  cache_result(nil)
end

#each(node = true, rel = nil, &block) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
# File 'lib/active_graph/node/has_n.rb', line 37

def each(node = true, rel = nil, &block)
  return [] unless node || rel

  if node && rel
    result_nodes.zip(rels)
  elsif node
    result_nodes
  else
    rels
  end.each(&block)
end

#each_rel(&block) ⇒ Object



49
50
51
# File 'lib/active_graph/node/has_n.rb', line 49

def each_rel(&block)
  rels.each(&block)
end

#empty?(*args) ⇒ Boolean

Returns:



64
65
66
# File 'lib/active_graph/node/has_n.rb', line 64

def empty?(*args)
  @deferred_objects.empty? && @enumerable.empty?(*args)
end

#init_cacheObject



107
108
109
110
# File 'lib/active_graph/node/has_n.rb', line 107

def init_cache
  @cached_rels ||= []
  @cached_result ||= []
end

#inspectObject

States: Default



25
26
27
28
# File 'lib/active_graph/node/has_n.rb', line 25

def inspect
  formatted_nodes = ::ActiveGraph::Node::NodeListFormatter.new(result_nodes)
  "#<AssociationProxy #{@query_proxy.context} #{formatted_nodes.inspect}>"
end

#lengthObject



56
57
58
# File 'lib/active_graph/node/has_n.rb', line 56

def length
  @deferred_objects.length + @enumerable.length
end

#relsObject



117
118
119
# File 'lib/active_graph/node/has_n.rb', line 117

def rels
  @cached_rels || super.tap { |rels| rels.each { |rel| add_to_cache(nil, rel)  } }
end

#replace_with(*args) ⇒ Object



137
138
139
140
141
142
143
144
# File 'lib/active_graph/node/has_n.rb', line 137

def replace_with(*args)
  nodes = @query_proxy.replace_with(*args).to_a
  if @query_proxy.start_object.try(:new_record?)
    @cached_result = nil
  else
    cache_result(nodes)
  end
end

#resultObject



76
77
78
# File 'lib/active_graph/node/has_n.rb', line 76

def result
  (@deferred_objects || []) + result_without_deferred
end

#result_cache_proc_cacheObject



125
126
127
# File 'lib/active_graph/node/has_n.rb', line 125

def result_cache_proc_cache
  @result_cache_proc_cache ||= @result_cache_proc.call if @result_cache_proc
end

#result_idsObject



96
97
98
99
100
# File 'lib/active_graph/node/has_n.rb', line 96

def result_ids
  result.map do |object|
    object.is_a?(ActiveGraph::Node) ? object.id : object
  end
end

#result_nodesObject



86
87
88
89
90
# File 'lib/active_graph/node/has_n.rb', line 86

def result_nodes
  return result_objects if !@query_proxy.model

  map_results_as_nodes(result_objects)
end

#result_objectsObject



92
93
94
# File 'lib/active_graph/node/has_n.rb', line 92

def result_objects
  @deferred_objects + result_without_deferred
end

#result_without_deferredObject



80
81
82
83
84
# File 'lib/active_graph/node/has_n.rb', line 80

def result_without_deferred
  cache_query_proxy_result if !@cached_result

  @cached_result
end

#serializable_hash(options = {}) ⇒ Object



172
173
174
# File 'lib/active_graph/node/has_n.rb', line 172

def serializable_hash(options = {})
  to_a.map { |record| record.serializable_hash(options) }
end

#sizeObject



60
61
62
# File 'lib/active_graph/node/has_n.rb', line 60

def size
  @deferred_objects.size + @enumerable.size
end