Module: GraphQL::Schema::Member::HasFields Private

Included in:
Interface::DefinitionMethods, GraphQL::Schema::Mutation, Object, Subscription
Defined in:
lib/graphql/schema/member/has_fields.rb

Overview

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

Shared code for Objects, Interfaces, Mutations, Subscriptions

Constant Summary collapse

RUBY_KEYWORDS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

A list of Ruby keywords.

[:class, :module, :def, :undef, :begin, :rescue, :ensure, :end, :if, :unless, :then, :elsif, :else, :case, :when, :while, :until, :for, :break, :next, :redo, :retry, :in, :do, :return, :yield, :super, :self, :nil, :true, :false, :and, :or, :not, :alias, :defined?, :BEGIN, :END, :__LINE__, :__FILE__]
GRAPHQL_RUBY_KEYWORDS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

A list of GraphQL-Ruby keywords.

[:context, :object, :raw_value]
CONFLICT_FIELD_NAMES =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

A list of field names that we should advise users to pick a different resolve method name.

Set.new(GRAPHQL_RUBY_KEYWORDS + RUBY_KEYWORDS + Object.instance_methods)

Instance Method Summary collapse

Instance Method Details

#add_field(field_defn, method_conflict_warning: field_defn.method_conflict_warning?) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Register this field with the class, overriding a previous one if needed.

Parameters:


72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/graphql/schema/member/has_fields.rb', line 72

def add_field(field_defn, method_conflict_warning: field_defn.method_conflict_warning?)
  # Check that `field_defn.original_name` equals `resolver_method` and `method_sym` --
  # that shows that no override value was given manually.
  if method_conflict_warning && CONFLICT_FIELD_NAMES.include?(field_defn.resolver_method) && field_defn.original_name == field_defn.resolver_method && field_defn.original_name == field_defn.method_sym
    warn(conflict_field_name_warning(field_defn))
  end
  prev_defn = own_fields[field_defn.name]

  case prev_defn
  when nil
    own_fields[field_defn.name] = field_defn
  when Array
    prev_defn << field_defn
  when GraphQL::Schema::Field
    own_fields[field_defn.name] = [prev_defn, field_defn]
  else
    raise "Invariant: unexpected previous field definition for #{field_defn.name.inspect}: #{prev_defn.inspect}"
  end

  nil
end

#all_field_definitionsObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.


118
119
120
121
122
123
124
125
126
127
128
# File 'lib/graphql/schema/member/has_fields.rb', line 118

def all_field_definitions
  all_fields = {}
  ancestors.reverse_each do |ancestor|
    if ancestor.respond_to?(:own_fields)
      all_fields.merge!(ancestor.own_fields)
    end
  end
  all_fields = all_fields.values
  all_fields.flatten!
  all_fields
end

#field(*args, **kwargs, &block) ⇒ GraphQL::Schema::Field

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Add a field to this object or interface with the given definition

Returns:

See Also:

  • for method signature

11
12
13
14
15
# File 'lib/graphql/schema/member/has_fields.rb', line 11

def field(*args, **kwargs, &block)
  field_defn = field_class.from_options(*args, owner: self, **kwargs, &block)
  add_field(field_defn)
  field_defn
end

#field_class(new_field_class = nil) ⇒ Class

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns The class to initialize when adding fields to this kind of schema member.

Returns:

  • (Class)

    The class to initialize when adding fields to this kind of schema member


95
96
97
98
99
100
101
102
103
# File 'lib/graphql/schema/member/has_fields.rb', line 95

def field_class(new_field_class = nil)
  if new_field_class
    @field_class = new_field_class
  elsif defined?(@field_class) && @field_class
    @field_class
  else
    find_inherited_value(:field_class, GraphQL::Schema::Field)
  end
end

#fields(context = GraphQL::Query::NullContext) ⇒ Hash<String => GraphQL::Schema::Field>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns Fields on this object, keyed by name, including inherited fields.

Returns:

  • (Hash<String => GraphQL::Schema::Field>)

    Fields on this object, keyed by name, including inherited fields


18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/graphql/schema/member/has_fields.rb', line 18

def fields(context = GraphQL::Query::NullContext)
  warden = Warden.from_context(context)
  is_object = self.respond_to?(:kind) && self.kind.object?
  # Local overrides take precedence over inherited fields
  visible_fields = {}
  for ancestor in ancestors
    if ancestor.respond_to?(:own_fields) &&
        (is_object ? visible_interface_implementation?(ancestor, context, warden) : true)

      ancestor.own_fields.each do |field_name, fields_entry|
        # Choose the most local definition that passes `.visible?` --
        # stop checking for fields by name once one has been found.
        if !visible_fields.key?(field_name) && (f = Warden.visible_entry?(:visible_field?, fields_entry, context, warden))
          visible_fields[field_name] = f
        end
      end
    end
  end
  visible_fields
end

#get_field(field_name, context = GraphQL::Query::NullContext) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.


39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/graphql/schema/member/has_fields.rb', line 39

def get_field(field_name, context = GraphQL::Query::NullContext)
  warden = Warden.from_context(context)
  is_object = self.respond_to?(:kind) && self.kind.object?
  for ancestor in ancestors
    if ancestor.respond_to?(:own_fields) &&
        (is_object ? visible_interface_implementation?(ancestor, context, warden) : true) &&
        (f_entry = ancestor.own_fields[field_name]) &&
        (f = Warden.visible_entry?(:visible_field?, f_entry, context, warden))
      return f
    end
  end
  nil
end

#global_id_field(field_name, **kwargs) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.


105
106
107
108
109
110
111
# File 'lib/graphql/schema/member/has_fields.rb', line 105

def global_id_field(field_name, **kwargs)
  id_resolver = GraphQL::Relay::GlobalIdResolve.new(type: self)
  field field_name, "ID", **kwargs, null: false
  define_method(field_name) do
    id_resolver.call(object, {}, context)
  end
end

#own_fieldsHash<String => GraphQL::Schema::Field, Array<GraphQL::Schema::Field>>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns Fields defined on this class specifically, not parent classes.

Returns:


114
115
116
# File 'lib/graphql/schema/member/has_fields.rb', line 114

def own_fields
  @own_fields ||= {}
end