Class: ElasticGraph::SchemaDefinition::SchemaElements::FieldPath::Resolver

Inherits:
Object
  • Object
show all
Defined in:
lib/elastic_graph/schema_definition/schema_elements/field_path.rb

Overview

Responsible for resolving a particular field path (given as a string) into a ‘FieldPath` object.

Cannot be instantiated until the user has finished defining the schema. If we allowed it to be used before then, it creates a situation where the order of definition matters. In addition, this class optimizes performance by memoizing some things based on the current state, and if the state is updated after an instance is created, inaccurate results could be produced.

Instance Method Summary collapse

Constructor Details

#initialize(state) ⇒ Resolver

Returns a new instance of Resolver.



59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/elastic_graph/schema_definition/schema_elements/field_path.rb', line 59

def initialize(state)
  unless state.user_definition_complete
    raise Errors::SchemaError,
      "A `FieldPath::Resolver` cannot be created before the user definition of the schema is complete."
  end

  @indexing_fields_by_public_name_by_type = ::Hash.new do |hash, type|
    hash[type] = type
      .indexing_fields_by_name_in_index
      .values
      .to_h { |f| [f.name, f] }
  end
end

Instance Method Details

#determine_nested_paths(type, path_string) ⇒ Object

Determines the nested paths in the given ‘path_string` Returns `nil` if no field at that path can be found, and returns `[]` if no nested paths are found.

Nested paths are represented as the full path to the nested fields For example: a ‘path_string` of “foo.bar.baz” might have nested paths [“foo”, “foo.bar.baz”]



102
103
104
105
106
107
108
109
110
111
# File 'lib/elastic_graph/schema_definition/schema_elements/field_path.rb', line 102

def determine_nested_paths(type, path_string)
  field_path = resolve_public_path(type, path_string) { true }
  return nil unless field_path

  parts_so_far = [] # : ::Array[::String]
  field_path.path_parts.filter_map do |field|
    parts_so_far << field.name
    parts_so_far.join(".") if field.nested?
  end
end

#resolve_public_path(type, path_string) ⇒ Object

Resolves the given ‘path_string` relative to the given `type`. Returns `nil` if no field at that path can be found.

Requires a block which will be called to determine if a parent field is valid to resolve through. For example, the caller may want to disallow all parent list fields, or disallow ‘nested` parent list fields while allowing `object` parent list fields.



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/elastic_graph/schema_definition/schema_elements/field_path.rb', line 79

def resolve_public_path(type, path_string)
  field = nil # : Field?

  path_parts = path_string.split(".").map do |field_name|
    return nil unless type
    return nil if field && !yield(field)
    return nil unless (field = @indexing_fields_by_public_name_by_type.dig(type, field_name))
    type = field.type.unwrap_list.as_object_type
    field
  end

  return nil if path_parts.empty?

  FieldPath.send(:new, path_parts.first, path_parts.last, path_parts)
end