Class: Jinx::ReferencePathVisitor

Inherits:
ReferenceVisitor show all
Defined in:
lib/jinx/resource/reference_path_visitor.rb

Overview

A ReferencePathVisitor traverses an attribute path.

For example, given the attributes:

favorites : Person -> Book
authors : Book -> Author
publications : Author -> Book

then a path visitor given by:

ReferencePathVisitor.new(Person, [:favorites, :authors, :publications])

visits the transitive closure of books published by the authors of a person’s favorite books.

Instance Attribute Summary

Attributes inherited from Visitor

#lineage, #options, #visited

Instance Method Summary collapse

Methods inherited from ReferenceVisitor

#attributes_to_visit

Methods inherited from Visitor

#clear, #current, #cyclic_nodes, #depth_first?, #filter, #from, #node_children, #root, #sync, #to_enum, #visit, #visit_children, #visit_node_and_children, #visit_recursive, #visit_root, #visited?

Constructor Details

#initialize(klass, attributes, opts = nil) ⇒ ReferenceVisitor

Returns a visitor which traverses the given path attributes starting at an instance of the given type.

Parameters:

  • the (Class)

    type of object to begin the traversal

  • the (<Symbol>)

    attributes to traverse

  • opts (Symbol, {Symbol => Object}) (defaults to: nil)

    the visit options



24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/jinx/resource/reference_path_visitor.rb', line 24

def initialize(klass, attributes, opts=nil)
  # augment the attributes path as a [class, attribute] path
  path = klass.property_path(*attributes)
  # make the visitor
  super(opts) do |ref|
    # Collect the path attributes whose type is the ref type up to the
    # next position in the path.
    max = Math.min(lineage.size, path.size)
    pas = (0...max).map { |i| path[i].attribute if path[i].declarer === ref }
    pas.compact!
    ref.class.attribute_filter(pas)
  end
end