如何在GraphQL-Ruby的Edge中暴露多对多关联表的属性?
在GraphQL-Ruby中为关联Edge添加ListItem属性
要实现Edge包含ListItem的position、updatedAt属性,核心是让Edge直接关联ListItem记录,而非Item本身。以下是具体实现步骤:
1. 定义自定义Edge类型
创建继承自GraphQL::Types::Relay::BaseEdge的自定义Edge,添加ListItem的属性字段:
# app/graphql/types/list_item_edge.rb module Types class ListItemEdge < GraphQL::Types::Relay::BaseEdge # 指定Edge对应的Node类型为ItemType node_type Types::ItemType # 定义ListItem的属性字段 field :position, Integer, null: false field :updated_at, GraphQL::Types::ISO8601DateTime, null: false, method: :updated_at # 字段解析方法,直接从ListItem实例取值 def position object.position end def updated_at object.updated_at end end end
2. 定义自定义Connection类型
创建关联上述Edge的Connection类型:
# app/graphql/types/list_item_connection.rb module Types class ListItemConnection < GraphQL::Types::Relay::BaseConnection edge_type Types::ListItemEdge end end
3. 修改ListType的items字段
在ListType中,让items字段返回ListItem集合而非Item集合,并使用自定义Connection:
# app/graphql/types/list_type.rb module Types class ListType < Types::BaseObject field :id, ID, null: false field :title, String, null: false field :created_at, GraphQL::Types::ISO8601DateTime, null: false # 使用自定义的ListItemConnection field :items, Types::ListItemConnection, null: false do argument :first, Integer, required: false argument :after, String, required: false end def items(**args) # 按position排序返回当前列表的ListItem集合 list_items = object.list_items.order(position: :asc) # 用Relay连接包装器处理分页参数 GraphQL::Relay::Connection.from_nodes(list_items, args) end end end
原理说明
- 此时resolve返回的是ListItem实例集合,Edge的
object就是ListItem记录,因此可以直接读取其position、updated_at属性。 - Edge的
node字段会自动通过ListItem关联的item属性获取Item实例,无需额外配置。
现在执行你提供的查询,就能得到预期结果:
list(id: $id) { title createdAt items { edges { position updatedAt node { id title thumbnailUrl } } } }
内容的提问来源于stack exchange,提问作者ScottM
相关产品推荐
相关产品推荐

