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.



70
71
72
73
# File 'lib/gql/node.rb', line 70

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

Instance Attribute Details

#ast_nodeObject (readonly)

Returns the value of attribute ast_node.



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

def ast_node
  @ast_node
end

#contextObject (readonly)

Returns the value of attribute context.



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

def context
  @context
end

#targetObject (readonly)

Returns the value of attribute target.



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

def target
  @target
end

#variablesObject (readonly)

Returns the value of attribute variables.



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

def variables
  @variables
end

Class Method Details

.call(*names, &block) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/gql/node.rb', line 13

def call(*names, &block)
  names_with_result_class = names.extract_options!

  names.each do |name|
    names_with_result_class[name] = nil
  end

  names_with_result_class.each do |name, result_class|
    method = block || lambda { |*args| target.public_send(name, *args) }
    call_class = Call.build_class(result_class, method)

    self.const_set "#{name.to_s.camelize}Call", call_class
    self.call_classes = call_classes.merge(name => call_class)
  end
end

.cursor(name = nil, &block) ⇒ Object



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

def cursor(name = nil, &block)
  if name
    field :cursor, &-> { target.public_send(name) }
  elsif block_given?
    field :cursor, &block
  end
end

.field(*names, &block) ⇒ Object



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

def field(*names, &block)
  options = names.extract_options!

  names.each do |name|
    method = block || lambda { target.public_send(name) }
    field_type_class = options.delete(:field_type_class) || Field

    unless field_type_class <= Field
      raise Errors::InvalidNodeClass.new(field_type_class, Field)
    end

    field_class = field_type_class.build_class(method, options)

    self.const_set "#{name.to_s.camelize}Field", field_class
    self.field_classes = field_classes.merge(name => field_class)
  end
end

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



55
56
57
58
59
60
61
62
63
64
65
# File 'lib/gql/node.rb', line 55

def method_missing(method, *names, &block)
  if field_type_class = GQL.field_types[method]
    options = names.extract_options!

    field(*names, options.merge(field_type_class: field_type_class), &block)
  else
    super
  end
rescue NoMethodError => exc
  raise Errors::UndefinedFieldType, method
end

Instance Method Details

#raw_valueObject



124
125
126
# File 'lib/gql/node.rb', line 124

def raw_value
  nil
end

#valueObject



75
76
77
78
79
80
81
82
83
# File 'lib/gql/node.rb', line 75

def value
  if ast_call = ast_node.call
    value_of_call ast_call
  elsif ast_fields = ast_node.fields
    value_of_fields ast_fields
  else
    raw_value
  end
end

#value_of_call(ast_call) ⇒ Object



85
86
87
88
89
90
91
92
93
94
# File 'lib/gql/node.rb', line 85

def value_of_call(ast_call)
  call_class = self.class.call_classes[ast_call.name]

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

  call = call_class.new(self, ast_call, target, variables, context)
  call.execute
end

#value_of_field(ast_field) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/gql/node.rb', line 104

def value_of_field(ast_field)
  case ast_field.name
  when :node
    field = self.class.new(ast_field, target, variables, context)
    field.value
  else
    method = Field::Method.new(target, context)
    field_class = self.class.field_classes[ast_field.name]

    if field_class.nil?
      raise Errors::UndefinedField.new(ast_field.name, self.class.superclass)
    end

    next_target = method.execute(field_class.method)

    field = field_class.new(ast_field, next_target, variables, context)
    field.value
  end
end

#value_of_fields(ast_fields) ⇒ Object



96
97
98
99
100
101
102
# File 'lib/gql/node.rb', line 96

def value_of_fields(ast_fields)
  ast_fields.reduce({}) do |memo, ast_field|
    key = ast_field.alias_name || ast_field.name

    memo.merge key => value_of_field(ast_field)
  end
end