Class: GQL::Node

Inherits:
Object
  • Object
show all
Defined in:
lib/gql/node.rb

Direct Known Subclasses

Connection, Field

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ast_node, target, variables, context) ⇒ Node

Returns a new instance of Node.



66
67
68
69
# File 'lib/gql/node.rb', line 66

def initialize(ast_node, target, variables, context)
  @ast_node, @__target = ast_node, target
  @variables, @__context = variables, context
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object



111
112
113
114
115
116
117
118
119
# File 'lib/gql/node.rb', line 111

def method_missing(method, *args, &block)
  if __target.respond_to? method
    __target.public_send method, *args, &block
  else
    super
  end
rescue NoMethodError => exc
  raise Errors::UndefinedField.new(method, self.class)
end

Instance Attribute Details

#__contextObject (readonly)

Returns the value of attribute __context.



64
65
66
# File 'lib/gql/node.rb', line 64

def __context
  @__context
end

#__targetObject (readonly)

Returns the value of attribute __target.



64
65
66
# File 'lib/gql/node.rb', line 64

def __target
  @__target
end

Class Method Details

.call(name, options = {}, &block) ⇒ Object



19
20
21
22
23
24
25
26
# File 'lib/gql/node.rb', line 19

def call(name, options = {}, &block)
  definition = {
    returns: options[:returns],
    body: block || lambda { |*args| __target.public_send(name, *args) }
  }

  self.call_definitions = call_definitions.merge(name => definition)
end

.cursor(method_name) ⇒ Object



13
14
15
16
17
# File 'lib/gql/node.rb', line 13

def cursor(method_name)
  define_method :cursor do
    __target.send(method_name).to_s
  end
end

.field(*names, base_class: nil, node_class: nil, connection_class: nil) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/gql/node.rb', line 32

def field(*names, base_class: nil, node_class: nil, connection_class: nil)
  classes = names.reduce({}) do |result, name|
    field_class = Class.new(base_class || Field)
    field_class.const_set :NAME, name
    field_class.const_set :NODE_CLASS, node_class
    field_class.const_set :CONNECTION_CLASS, connection_class

    self.const_set "#{name.to_s.camelize}Field", field_class

    result.merge name => field_class
  end

  self.field_classes = field_classes.merge(classes)
end

.fields(&block) ⇒ Object



28
29
30
# File 'lib/gql/node.rb', line 28

def fields(&block)
  instance_eval &block
end

.method_missing(method, *args, &block) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
# File 'lib/gql/node.rb', line 47

def method_missing(method, *args, &block)
  if base_class = Schema.fields[method]
    options = args.extract_options!

    field(*args, options.merge(base_class: base_class))
  else
    super
  end
rescue NoMethodError => exc
  raise Errors::UndefinedType, method
end

Instance Method Details

#__raw_valueObject



107
108
109
# File 'lib/gql/node.rb', line 107

def __raw_value
  nil
end

#__valueObject



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/gql/node.rb', line 71

def __value
  if ast_call = @ast_node.call
    definition = self.class.call_definitions[ast_call.name]

    raise Errors::UndefinedCall.new(ast_call.name, self.class) if definition.nil?

    call = Call.new(self, ast_call, __target, definition, @variables, __context)
    call.execute
  elsif ast_fields = @ast_node.fields
    ast_fields.reduce({}) do |memo, ast_field|
      key = ast_field.alias_name || ast_field.name

      val =
        case key
        when :node
          field = self.class.new(ast_field, __target, @variables, __context)
          field.__value
        when :cursor
          cursor
        else
          target = public_send(ast_field.name)
          field_class = self.class.field_classes[ast_field.name]

          raise Errors::InvalidNodeClass.new(field_class.superclass, Field) unless field_class < Field

          field = field_class.new(ast_field, target, @variables, __context)
          field.__value
        end

      memo.merge key => val
    end
  else
    __raw_value
  end
end