Graphql-ruby: Clever alternative for new class-style with pagination

Created on 19 Jun 2018  路  3Comments  路  Source: rmosolgo/graphql-ruby

Hello,

I have in my application about 50 models I need too paginate through. I'm reading the documentation and the code in order to find some elegant method to have all of that in one place and so fare I figured how to have the bare minimum but it still requires to create 50 connection files and I can't figure how to add an argument and a post resolver.

I wonder if someone around here could advise me on that.

So far I've:

# frozen_string_literal: true

module Types
  class DesignerConnection < BaseConnection
    set_edge_type
  end
end
# frozen_string_literal: true

module Types
  class DesignerEdge < BaseEdge
    set_node_type
  end
end
module Types
  class BaseEdge < GraphQL::Types::Relay::BaseEdge
    def self.set_node_type
      node_name = graphql_name.split('::').last.sub('Edge', 'Type')
      node_type = Types.const_get(node_name, false)
      node_type(node_type)
    end
  end
end
# frozen_string_literal: true

module Types
  class BaseConnection < GraphQL::Types::Relay::BaseConnection
    field :total_count, Integer, null: false
    def total_count
      object.nodes.size
    end

    field :count, Integer, null: false
    def count
      @object.edge_nodes.count
    end

    def self.set_edge_type
      edge_name = graphql_name.split('::').last.sub('Connection', 'Edge')
      edge_type = Types.const_get(edge_name, false)
      edge_type(edge_type)
    end
  end
end

1) I tried to add arguments to the BaseConnection but it doesn't accept it. Any idea how to achieve this?

2) As I try to resolve the Edge name dynamically, I've to use the set_edge_type from the child class. Any idea how I could achieve the same without the set_edge_type?

Most helpful comment

I know I'm late to the party, but for completeness shake and since this issue is still open:

module Types
  class BaseObject < GraphQL::Schema::Object
    connection_type_class BaseConnection
  end
end

All 3 comments

We have the same problem here and my coleague did a monkey patch for it, so all created connections inherit from this definition.

The file can be found here: https://github.com/rmosolgo/graphql-ruby/blob/master/lib/graphql/relay/connection_type.rb#L16

Although this works, it isn't the best solution. Maybe in the future we will have an API to change the default connection definition on the schema itself.

# app/graphql/my_schema.rb

module GraphQL
  module Relay
    module ConnectionType
      def self.create_type(wrapped_type, edge_type: nil, edge_class: GraphQL::Relay::Edge, nodes_field: ConnectionType.default_nodes_field, &block)
        custom_edge_class = edge_class

        ObjectType.define do
          type_name = wrapped_type.is_a?(GraphQL::BaseType) ? wrapped_type.name : wrapped_type.graphql_name
          edge_type ||= wrapped_type.edge_type
          name("#{type_name}Connection")
          description("The connection type for #{type_name}.")
          field :edges, types[edge_type], "A list of edges.", edge_class: custom_edge_class, property: :edge_nodes

          if nodes_field
            field :nodes, types[wrapped_type],  "A list of nodes.", property: :edge_nodes
          end

          field :pageInfo, !PageInfo, "Information to aid in pagination.", property: :page_info
          relay_node_type(wrapped_type)

          # patch

          field :totalCount, types.Int, 'Total count', resolve: -> (object, _, _) do
            object.nodes.count
          end

          field :totalPages, types.Int, 'Total pages',   resolve: -> (object, _, _) do
            object.nodes.total_pages
          end

          # patch

          block && instance_eval(&block)
        end
      end
    end
  end
end

class MySchema < GraphQL::Schema
  max_complexity 400

  query QueryType
  mutation MutationType
end

I know I'm late to the party, but for completeness shake and since this issue is still open:

module Types
  class BaseObject < GraphQL::Schema::Object
    connection_type_class BaseConnection
  end
end

@freestyl3r I think that when the issue was started this feature wasn't implemented. It looks much cleaner now, thanks for the heads up.

Was this page helpful?
0 / 5 - 0 ratings