123456789_123456789_123456789_123456789_123456789_

Module: GraphQL::Client::Schema::ObjectType

Relationships & Source Files
Namespace Children
Classes:
Extension / Inclusion / Inheritance Descendants
Included In:
Defined in: lib/graphql/client/schema/object_type.rb

Class Method Summary

Instance Method Summary

Class Method Details

.new(type, fields = {})

[ GitHub ]

  
# File 'lib/graphql/client/schema/object_type.rb', line 12

def self.new(type, fields = {})
  Class.new(ObjectClass) do
    extend BaseType
    extend ObjectType

    define_singleton_method(:type) { type }
    define_singleton_method(:fields) { fields }

    const_set(:READERS, {})
    const_set(:PREDICATES, {})
  end
end

Instance Method Details

#cast(value, errors)

[ GitHub ]

  
# File 'lib/graphql/client/schema/object_type.rb', line 116

def cast(value, errors)
  case value
  when Hash
    new(value, errors)
  when NilClass
    nil
  else
    raise InvariantError, "expected value to be a Hash, but was #{value.class}"
  end
end

#define_class(definition, ast_nodes)

[ GitHub ]

  
# File 'lib/graphql/client/schema/object_type.rb', line 69

def define_class(definition, ast_nodes)
  # First, gather all the ast nodes representing a certain selection, by name.
  # We gather AST nodes into arrays so that multiple selections can be grouped, for example:
  #
  #   {
  #     f1 { a b }
  #     f1 { b c }
  #   }
  #
  # should be treated like `f1 { a b c }`
  field_nodes = {}
  ast_nodes.each do |ast_node|
    ast_node.selections.each do |selected_ast_node|
      gather_selections(field_nodes, definition, selected_ast_node)
    end
  end

  # After gathering all the nodes by name, prepare to create methods and classes for them.
  field_classes = {}
  field_nodes.each do |result_name, field_ast_nodes|
    # `result_name` might be an alias, so make sure to get the proper name
    field_name = field_ast_nodes.first.name
    field_definition = definition.client.schema.get_field(type.graphql_name, field_name)
    field_return_type = field_definition.type
    field_classes[result_name.to_sym] = schema_module.define_class(definition, field_ast_nodes, field_return_type)
  end

  spreads = definition.indexes[:spreads][ast_nodes.first]

  WithDefinition.new(self, field_classes, definition, spreads)
end

#define_field(name, type)

[ GitHub ]

  
# File 'lib/graphql/client/schema/object_type.rb', line 101

def define_field(name, type)
  name = name.to_s
  method_name = ActiveSupport::Inflector.underscore(name)

  define_method(method_name) do
    @casted_data.fetch(name) do
      @casted_data[name] = type.cast(@data[name], @errors.filter_by_path(name))
    end
  end

  define_method("#{method_name}?") do
    @data[name] ? true : false
  end
end

#gather_selections(fields, definition, selected_ast_node) (private)

Given an AST selection on this object, gather it into fields if it applies. If it’s a fragment, continue recursively checking the selections on the fragment.

[ GitHub ]

  
# File 'lib/graphql/client/schema/object_type.rb', line 131

def gather_selections(fields, definition, selected_ast_node)
  case selected_ast_node
  when GraphQL::Language::Nodes::InlineFragment
    continue_selection = if selected_ast_node.type.nil?
      true
    else
      type_condition = definition.client.get_type(selected_ast_node.type.name)
      applicable_types = definition.client.possible_types(type_condition)
      # continue if this object type is one of the types matching the fragment condition
      applicable_types.include?(type)
    end

    if continue_selection
      selected_ast_node.selections.each do |next_selected_ast_node|
        gather_selections(fields, definition, next_selected_ast_node)
      end
    end
  when GraphQL::Language::Nodes::FragmentSpread
    fragment_definition = definition.document.definitions.find do |defn|
      defn.is_a?(GraphQL::Language::Nodes::FragmentDefinition) && defn.name == selected_ast_node.name
    end
    type_condition = definition.client.get_type(fragment_definition.type.name)
    applicable_types = definition.client.possible_types(type_condition)
    # continue if this object type is one of the types matching the fragment condition
    continue_selection = applicable_types.include?(type)

    if continue_selection
      fragment_definition.selections.each do |next_selected_ast_node|
        gather_selections(fields, definition, next_selected_ast_node)
      end
    end
  when GraphQL::Language::Nodes::Field
    operation_definition_for_field = definition.indexes[:definitions][selected_ast_node]
    # Ignore fields defined in other documents.
    if definition.source_document.definitions.include?(operation_definition_for_field)
      field_method_name = selected_ast_node.alias || selected_ast_node.name
      ast_nodes = fields[field_method_name] ||= []
      ast_nodes << selected_ast_node
    end
  else
    raise "Unexpected selection node: #{selected_ast_node}"
  end
end