class GraphQL::Schema::BuildFromDefinition::ResolveMap::DefaultResolve

Public Class Methods

new(field_map, field_name) click to toggle source
# File lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb, line 6
def initialize(field_map, field_name)
  @field_map = field_map
  @field_name = field_name
end

Public Instance Methods

call(obj, args, ctx) click to toggle source

Make some runtime checks about how `obj` implements the `field_name`.

Create a new resolve function according to that implementation, then:

- update `field_map` with this implementation
- call the implementation now (to satisfy this field execution)

If `obj` doesn't implement `field_name`, raise an error.

# File lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb, line 19
def call(obj, args, ctx)
  method_name = @field_name
  if !obj.respond_to?(method_name)
    raise KeyError, "Can't resolve field #{method_name} on #{obj}"
  else
    method_arity = obj.method(method_name).arity
    resolver = case method_arity
    when 0, -1
      # -1 Handles method_missing, eg openstruct
      ->(o, a, c) { o.public_send(method_name) }
    when 1
      ->(o, a, c) { o.public_send(method_name, a) }
    when 2
      ->(o, a, c) { o.public_send(method_name, a, c) }
    else
      raise "Unexpected resolve arity: #{method_arity}. Must be 0, 1, 2"
    end
    # Call the resolver directly next time
    @field_map[method_name] = resolver
    # Call through this time
    resolver.call(obj, args, ctx)
  end
end