Class: Rails::GraphQL::Type::Union

Inherits:
Rails::GraphQL::Type show all
Includes:
Helpers::Instantiable
Defined in:
lib/rails/graphql/type/union.rb

Overview

GraphQL UnionType

Unions represent an object that could be one of a list of GraphQL Object types. See spec.graphql.org/June2018/#UnionTypeDefinition

Constant Summary collapse

VALID_MEMBER_TYPES =

The list of accepted classes for members

[Type::Object].freeze

Constants inherited from Rails::GraphQL::Type

KINDS

Instance Attribute Summary

Attributes included from Helpers::Instantiable

#event

Class Method Summary collapse

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 type is member of any of this union members



35
36
37
# File 'lib/rails/graphql/type/union.rb', line 35

def =~(other)
  super || all_members.any? { |item| other =~ item }
end

.append(*others) ⇒ Object

Use this method to add members to the union

Raises:



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

def append(*others)
  return if others.blank?

  others.flatten!
  others.map! do |item|
    next item unless item.is_a?(Symbol)
    GraphQL.type_map.fetch(item, namespaces: namespaces)
  end

  checker = others.map { |item| item.try(:base_type) }.uniq
  raise ArgumentError, (+<<~MSG).squish unless checker.size === 1
    All the union members must be of the same base class.
  MSG

  check_types = members? ? [of_kind] : VALID_MEMBER_TYPES
  raise ArgumentError, (+<<~MSG).squish unless (check_types & checker).size === 1
    A union cannot contain members of different base classes.
  MSG

  members.concat(others)
end

.inspectObject



77
78
79
80
81
82
83
84
85
# File 'lib/rails/graphql/type/union.rb', line 77

def inspect
  return super if self.eql?(Type::Union)
  (+<<~INFO).squish << '>'
    #<GraphQL::Union #{gql_name}
    (#{all_members.size})
    {#{all_members.map(&:gql_name).join(' | ')}}
    #{inspect_directives}
  INFO
end

.of_kindObject

Return the base type of the objects on this union



29
30
31
# File 'lib/rails/graphql/type/union.rb', line 29

def of_kind
  members.first.base_type
end

.type_for(value) ⇒ Object

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



24
25
26
# File 'lib/rails/graphql/type/union.rb', line 24

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

.validate!Object

Check if the union definition is valid

Raises:



63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/rails/graphql/type/union.rb', line 63

def validate!(*)
  super if defined? super

  members = all_members
  raise ArgumentError, (+<<~MSG).squish unless members.size >= 1
    A union must contain at least one member.
  MSG

  size = members.lazy.map(&:base_type).uniq.force.size
  raise ArgumentError, (+<<~MSG).squish unless size.eql?(1)
    All the members of the union must contain the same base class.
  MSG
end