Class: ElasticGraph::GraphQL::Schema::RelationJoin

Inherits:
Object
  • Object
show all
Defined in:
lib/elastic_graph/graphql/schema/relation_join.rb

Overview

Represents the join between documents for a relation.

Note that this class assumes a valid, well-formed schema definition, and makes no attempt to provide user-friendly errors when that is not the case. For example, we assume that a nested relationship field has at most one relationship directive. The (as yet unwritten) schema linter should validate such things eventually. When we do encounter errors at runtime (such as getting a scalar where we expect a list, or vice-versa), this class attempts to deal with as best as it can (sometimes simply picking one record or id from many!) and logs a warning.

Note: this class isn’t driven directly by tests. It exist purely to serve the needs of ElasticGraph::Resolvers::NestedRelationships, and is driven by that class’s tests. It lives here because it’s useful to expose it off of a ‘Field` since it’s a property of the field and that lets us memoize it on the field itself.

Defined Under Namespace

Modules: Cardinality

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.from(field) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/elastic_graph/graphql/schema/relation_join.rb', line 29

def self.from(field)
  return nil if (relation = field.relation).nil?

  doc_cardinality = field.type.collection? ? Cardinality::Many : Cardinality::One

  if relation.direction == :in
    # An inbound foreign key has some field (such as `foo_id`) on another document that points
    # back to the `id` field on the document with the relation.
    #
    # The cardinality of the document id field on an inbound relation is always 1 since
    # it is always the primary key `id` field.
    new(field, "id", relation.foreign_key, Cardinality::One, doc_cardinality, relation.additional_filter, relation.foreign_key_nested_paths)
  else
    # An outbound foreign key has some field (such as `foo_id`) on the document with the relation
    # that point out to the `id` field of another document.
    new(field, relation.foreign_key, "id", doc_cardinality, doc_cardinality, relation.additional_filter, relation.foreign_key_nested_paths)
  end
end

Instance Method Details

#blank_valueObject



48
49
50
# File 'lib/elastic_graph/graphql/schema/relation_join.rb', line 48

def blank_value
  doc_cardinality.blank_value
end

#extract_id_or_ids_from(document, log_warning) ⇒ Object

Extracts a single id or a list of ids from the given document, as required by the relation.



53
54
55
56
57
58
59
60
61
62
# File 'lib/elastic_graph/graphql/schema/relation_join.rb', line 53

def extract_id_or_ids_from(document, log_warning)
  id_or_ids = document.fetch(document_id_field_name) do
    log_warning.call(document: document, problem: "#{document_id_field_name} is missing from the document")
    blank_value
  end

  normalize_ids(id_or_ids) do |problem|
    log_warning.call(document: document, problem: "#{document_id_field_name}: #{problem}")
  end
end

#normalize_documents(response, &handle_warning) ⇒ Object

Normalizes the given documents, ensuring it has the expected cardinality.



65
66
67
# File 'lib/elastic_graph/graphql/schema/relation_join.rb', line 65

def normalize_documents(response, &handle_warning)
  doc_cardinality.normalize(response, handle_warning: handle_warning, &:id)
end