Class: GraphQL::Relay::BaseConnection

Inherits:
Object
  • Object
show all
Defined in:
lib/graphql/relay/base_connection.rb

Overview

Subclasses must implement:

- {#cursor_from_node}, which returns an opaque cursor for the given item
- {#sliced_nodes}, which slices by `before` & `after`
- {#paged_nodes}, which applies `first` & `last` limits

In a subclass, you have access to

- {#object}, the object which the connection will wrap
- {#first}, {#after}, {#last}, {#before} (arguments passed to the field)

Direct Known Subclasses

ArrayConnection, RelationConnection

Constant Summary collapse

CURSOR_SEPARATOR =

Just to encode data in the cursor, use something that won't conflict

"---"
CONNECTION_IMPLEMENTATIONS =

Map of collection classes -> connection_classes eg Array -> ArrayConnection

{}
METHODS_FROM_ARGUMENTS =

Provide easy access to provided arguments:

[:first, :after, :last, :before, :order]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(object, arguments) ⇒ BaseConnection

Returns a new instance of BaseConnection.


59
60
61
62
# File 'lib/graphql/relay/base_connection.rb', line 59

def initialize(object, arguments)
  @object = object
  @arguments = arguments
end

Instance Attribute Details

#argumentsObject (readonly)

Returns the value of attribute arguments


57
58
59
# File 'lib/graphql/relay/base_connection.rb', line 57

def arguments
  @arguments
end

#objectObject (readonly)

Returns the value of attribute object


57
58
59
# File 'lib/graphql/relay/base_connection.rb', line 57

def object
  @object
end

Class Method Details

.connection_for_items(items) ⇒ subclass of BaseConnection

Find a connection implementation suitable for exposing `items`

Parameters:

  • A (Object)

    collection of items (eg, Array, AR::Relation)

Returns:

  • (subclass of BaseConnection)

    a connection Class for wrapping `items`


38
39
40
41
42
43
44
45
46
47
# File 'lib/graphql/relay/base_connection.rb', line 38

def self.connection_for_items(items)
  implementation = CONNECTION_IMPLEMENTATIONS.find do |items_class, connection_class|
    items.is_a?(items_class)
  end
  if implementation.nil?
    raise("No connection implementation to wrap #{items.class} (#{items})")
  else
    implementation[1]
  end
end

.create_type(wrapped_type, &block) ⇒ Object

Create a connection which exposes edges of this type


21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/graphql/relay/base_connection.rb', line 21

def self.create_type(wrapped_type, &block)
  edge_type = wrapped_type.edge_type

  connection_type = ObjectType.define do
    name("#{wrapped_type.name}Connection")
    field :edges, types[edge_type]
    field :pageInfo, PageInfo, property: :page_info
    block && instance_eval(&block)
  end

  connection_type
end

.register_connection_implementation(items_class, connection_class) ⇒ Object

Add `connection_class` as the connection wrapper for `items_class` eg, `RelationConnection` is the implementation for `AR::Relation`

Parameters:

  • A (Class)

    class representing a collection (eg, Array, AR::Relation)

  • A (Class)

    class implementing Connection methods


53
54
55
# File 'lib/graphql/relay/base_connection.rb', line 53

def self.register_connection_implementation(items_class, connection_class)
  CONNECTION_IMPLEMENTATIONS[items_class] = connection_class
end

Instance Method Details

#afterObject

The value passed as `after:`, if there was one


77
78
79
80
81
# File 'lib/graphql/relay/base_connection.rb', line 77

METHODS_FROM_ARGUMENTS.each do |arg_name|
  define_method(arg_name) do
    arguments[arg_name]
  end
end

#beforeObject

The value passed as `before:`, if there was one


77
78
79
80
81
# File 'lib/graphql/relay/base_connection.rb', line 77

METHODS_FROM_ARGUMENTS.each do |arg_name|
  define_method(arg_name) do
    arguments[arg_name]
  end
end

#cursor_from_node(object) ⇒ Object

An opaque operation which returns a connection-specific cursor.

Raises:

  • (NotImplementedError)

104
105
106
# File 'lib/graphql/relay/base_connection.rb', line 104

def cursor_from_node(object)
  raise NotImplementedError, "must return a cursor for this object/connection pair"
end

#edgesObject

Wrap nodes in Edges so they expose cursors.


84
85
86
# File 'lib/graphql/relay/base_connection.rb', line 84

def edges
  @edges ||= paged_nodes.map { |item| Edge.new(item, self) }
end

#firstObject

The value passed as `first:`, if there was one


77
78
79
80
81
# File 'lib/graphql/relay/base_connection.rb', line 77

METHODS_FROM_ARGUMENTS.each do |arg_name|
  define_method(arg_name) do
    arguments[arg_name]
  end
end

#has_next_pageObject

Used by `pageInfo`


94
95
96
# File 'lib/graphql/relay/base_connection.rb', line 94

def has_next_page
  !!(first && sliced_nodes.count > first)
end

#has_previous_pageObject

Used by `pageInfo`


99
100
101
# File 'lib/graphql/relay/base_connection.rb', line 99

def has_previous_page
  !!(last && sliced_nodes.count > last)
end

#lastObject

The value passed as `last:`, if there was one


77
78
79
80
81
# File 'lib/graphql/relay/base_connection.rb', line 77

METHODS_FROM_ARGUMENTS.each do |arg_name|
  define_method(arg_name) do
    arguments[arg_name]
  end
end

#orderObject

The value passed as `order:`, if there was one


77
78
79
80
81
# File 'lib/graphql/relay/base_connection.rb', line 77

METHODS_FROM_ARGUMENTS.each do |arg_name|
  define_method(arg_name) do
    arguments[arg_name]
  end
end

#page_infoObject

Support the `pageInfo` field


89
90
91
# File 'lib/graphql/relay/base_connection.rb', line 89

def page_info
  self
end