Class: Rails::GraphQL::Type::Interface

Inherits:
Rails::GraphQL::Type show all
Extended by:
Helpers::WithAssignment, Helpers::WithFields
Includes:
Helpers::Instantiable
Defined in:
lib/rails/graphql/type/interface.rb

Overview

GraphQL InterfaceType

Interfaces represent a list of named fields and their types. See spec.graphql.org/June2018/#InterfaceTypeDefinition

This class doesn’t implements valid_output? nor any of the output like methods because the Object class that uses interface already fetches all the fields for its composition and does the validating and serializing process.

Constant Summary

Constants inherited from Rails::GraphQL::Type

KINDS

Instance Attribute Summary

Attributes included from Helpers::Instantiable

#event

Class Method Summary collapse

Methods included from Helpers::WithAssignment

assigned?, assigned_class, assigned_to, assigned_to=, extended, register!, safe_assigned_class, valid_assignment?

Methods included from Helpers::WithFields

change_field, configure_field, disable_fields, enable_fields, enabled_fields, extended, field, field_names, find_by_gid, find_field, find_field!, has_field?, import, import_all, proxy_field, safe_field, validate!

Methods inherited from Rails::GraphQL::Type

base_type, create!, decorate, find_by_gid, gid_base_class, input_type?, kind, kind_enum, leaf_type?, operational?, output_type?, to_gql_backtrace

Methods included from Helpers::WithDirectives

#all_directive_events, #all_directive_listeners, #directive_events?, #directive_listeners?, extended, included, #initialize_copy, #use, #using?, #validate!

Methods included from Helpers::WithGlobalID

#to_gid_param, #to_global_id

Methods included from Helpers::Registerable

#aliases, extended, #inherited, #register!, #registered?

Class Method Details

.=~(other) ⇒ Object

Check if the other type is equivalent, by checking if the other is an object and the object implements this interface



36
37
38
# File 'lib/rails/graphql/type/interface.rb', line 36

def =~(other)
  super || (other.object? && other.implements?(self))
end

.implemented(object, import_fields: true) ⇒ Object

When attaching an interface to an object, copy the fields and add to the list of types. Pre-existing same-named fields with are not equivalent produces an exception.



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/rails/graphql/type/interface.rb', line 43

def implemented(object, import_fields: true)
  import_fields = false if abstract?

  fields.each do |name, field|
    defined = object[field.name]
    raise ArgumentError, (+<<~MSG).squish unless defined || import_fields
      The "#{object.gql_name}" object must have a "#{field.gql_name}" field.
    MSG

    invalid = defined && defined !~ field
    raise ArgumentError, (+<<~MSG).squish if invalid
      The "#{object.gql_name}" object already has a "#{field.gql_name}" field and it
      is not equivalent to the one defined on the "#{gql_name}" interface.
    MSG

    object.proxy_field(field) if import_fields && !defined
  end

  types << object
end

.inspectObject



64
65
66
67
68
69
70
71
72
# File 'lib/rails/graphql/type/interface.rb', line 64

def inspect
  return super if self.eql?(Type::Interface)
  fields = @fields.values.map(&:inspect) if defined?(@fields)
  fields = fields.presence && +" {#{fields.join(', ')}}"

  directives = inspect_directives
  directives.prepend(' ') if directives.present?
  +"#<GraphQL::Interface #{gql_name}#{fields}#{directives}>"
end

.type_for(value) ⇒ Object

Figure out which one of the types is compatible with the provided value



30
31
32
# File 'lib/rails/graphql/type/interface.rb', line 30

def type_for(value, *)
  all_types&.reverse_each&.find { |t| t.valid_member?(value) }
end

.validateObject

Check if the given object is properly implementing this interface



75
76
77
78
# File 'lib/rails/graphql/type/interface.rb', line 75

def validate(*)
  # Don't validate interfaces since the fields are copied and
  # the interface might have broken field types due to namespaces
end