0

I'm in the process of building a GraphQL API in a Rails 7 application, using the graphql-ruby gem.

In the app, users can create lists of catalogue items, and their lists can be manually ordered. So the simplified ActiveRecords look a bit like this:

class List < ApplicationRecord has_many :list_items has_many :items, through: :list_items end class ListItem < ApplicationRecord belongs_to :list belongs_to :item # attributes include :position, :updated_at, etc. end class Item < ApplicationRecord has_many :list_items has_many :lists, through: :list_items end 

What I'd like to be able to do is to include the ListItem's attributes within the edge of the response, e.g.:

list(id: $id) { title createdAt items { edges { position updatedAt node { id title thumbnailUrl } } } } 

I've tried creating custom Connection and Edge objects, but have so far failed to work out how to express that the edge has a direct ActiveRecord equivalence to a particular ListItem record such that I can retrieve the necessary attributes.

2
  • It is unclear what's your question. edges is just list_items? What is node? You said lists can be ordered manually, but in your query there is not any order attribute, what do you mean? Commented Mar 17, 2023 at 12:29
  • I find this very useful github.com/kashiftufail/graphql_api_nested Commented Jun 7, 2023 at 10:54

1 Answer 1

1

So I think I've cracked it.

In my ListType I declare my custom connection:

module Types class ListType < Types::BaseObject field :id, ID, null: false field :title, String, null: false field :items, Types::ListItemConnectionType, connection: true def items object.list_items.order(:position) end end end 

The connection inherits from my base connection type but specifies the custom edge type:

module Types class ListItemConnectionType < Types::BaseConnection edge_type Types::ListItemEdgeType end end 

In the edge type, object.node is the ListItem record - so we need to provide a custom node method to expose its associated Item

module Types class ListItemEdgeType < Types::BaseEdge node_type(Types::ItemType) field :position, Integer field :updated_at, GraphQL::Types::ISO9601DateTime def position object.node.position end def updated_at object.node.updated_at end def node object.node.item end end end 

If anybody has an alternative approach, I'd love to hear it.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.