Class: Graphlyte::SelectionBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/graphlyte/selection_builder.rb

Overview

Main construct used to build selection sets, uses ‘method_missing` to select fields.

Note: instance methods are either symbolic or end in bangs to avoid shadowing legal field names.

Usage:

some_fields = %w[all these fields]
selection = SelectionBuilder.build(document) do
  foo                             # basic field
  bar(baz: 1) { x; y; z}          # field with sub-selection
  some_fields.each { self << _1 } # Adding fields dynamically
end

You should probably never need to call this directly - it is used to implement the DSL class.

Defined Under Namespace

Classes: Variable

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(document) ⇒ SelectionBuilder

Returns a new instance of SelectionBuilder.



97
98
99
# File 'lib/graphlyte/selection_builder.rb', line 97

def initialize(document)
  @document = document
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, **kwargs, &block) ⇒ Object (private)



176
177
178
179
180
181
182
183
# File 'lib/graphlyte/selection_builder.rb', line 176

def method_missing(name, *args, **kwargs, &block)
  if name.to_s.end_with?('=') && args.length == 1 && args[0].is_a?(WithField)
    aka = name.to_s.chomp('=')
    args[0].alias(aka)
  else
    select!(name.to_s.camelize, *args, **kwargs.transform_keys(&:camelize), &block)
  end
end

Class Method Details

.build(document, &block) ⇒ Object



91
92
93
94
95
# File 'lib/graphlyte/selection_builder.rb', line 91

def self.build(document, &block)
  return [] unless block_given?

  new(document).build!(&block)
end

Instance Method Details

#<<(selected) ⇒ Object

Selected can be:

  • a string or symbol (field name)

  • a Graphlyte::Syntax::Fragment,Field,InlineFragment

  • a SelectionBuilder::Variable (constructed with ‘DSL#var`).

Use of this method (or ‘select!`) is necessary to add fields that shadow core method or construct names (e.g. `if`, `open`, `else`, `class` and so on).



132
133
134
# File 'lib/graphlyte/selection_builder.rb', line 132

def <<(selected)
  select!(selected)
end

#argument_builder!Object



152
153
154
# File 'lib/graphlyte/selection_builder.rb', line 152

def argument_builder!
  @argument_builder ||= ArgumentBuilder.new(@document)
end

#build!Object



101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/graphlyte/selection_builder.rb', line 101

def build!
  old = @selection
  curr = []
  return curr unless block_given?

  @selection = curr

  yield self

  curr
ensure
  @selection = old
end

#on!(type_name, &block) ⇒ Object



115
116
117
118
119
120
121
# File 'lib/graphlyte/selection_builder.rb', line 115

def on!(type_name, &block)
  frag = Graphlyte::Syntax::InlineFragment.new
  frag.type_name = type_name
  frag.selection = build!(&block)

  select! frag
end

#select!(selected, *args, **kwargs, &block) ⇒ Object



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/graphlyte/selection_builder.rb', line 136

def select!(selected, *args, **kwargs, &block)
  case selected
  when Graphlyte::Syntax::Fragment
    @document.add_fragments(selected.required_fragments)
    @selection << Graphlyte::Syntax::FragmentSpread.new(name: selected.name)
  when Graphlyte::Syntax::InlineFragment, Graphlyte::Syntax::Field
    @selection << selected
  else
    field = new_field!(selected.to_s, args)
    field.arguments = argument_builder!.build(kwargs)
    field.selection += self.class.build(@document, &block)

    WithField.new(field, self)
  end
end