You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在GraphQL外部利用GraphQL-ruby定义的类型格式化数据?

直接用GraphQL类型格式化数据(无需执行内部查询)

针对你使用GraphQL-Ruby的场景,完全可以直接通过实例化已定义的GraphQL类型、模拟字段解析逻辑来格式化数据,不用执行内部GraphQL查询。以下是具体实现方案:

1. 正确初始化GraphQL类型对象

GraphQL-Ruby的BaseObject(即你的Types::BaseObject)支持通过initialize方法传入数据源object和GraphQL上下文context,注意context必须是GraphQL::Query::Context实例,不能用普通哈希:

# 构建合法的GraphQL上下文
context = GraphQL::Query::Context.new(values: { "id_suffix" => "foo" })
# 初始化UserType实例,传入数据源和上下文
typed_object = Types::UserType.new(object: User.find(1), context: context)

此时直接调用类型中定义的字段方法(比如custom_id)就能得到解析后的值:

typed_object.custom_id # => "1foo"

2. 实现to_h方法批量格式化所有字段

要一次性把所有字段转成哈希,可以给基础类型添加一个通用的序列化模块,模拟GraphQL解析所有字段的逻辑:

# 定义通用序列化模块
module TypeSerializable
  def to_h
    self.class.fields.each_with_object({}) do |(field_name, field_def), hash|
      value = resolve_field(field_def)
      # 嵌套类型递归转哈希(如果嵌套类型也包含该模块)
      hash[field_name] = value.respond_to?(:to_h) ? value.to_h : value
    end
  end

  private

  def resolve_field(field_def)
    # 优先调用类型中自定义的字段方法(比如你的custom_id)
    if respond_to?(field_def.name)
      public_send(field_def.name)
    else
      # 无自定义方法时,直接取数据源object的对应属性
      object.public_send(field_def.name)
    end
  end
end

# 在你的基础类型中引入该模块
class Types::BaseObject < GraphQL::Schema::Object
  include TypeSerializable
end

现在你就能直接调用to_h得到格式化后的哈希:

typed_object.to_h # => { "id" => 1, "custom_id" => "1foo" }

说明

  • 这个方案完全模拟了GraphQL解析字段的逻辑:优先使用类型中定义的实例方法作为字段解析器,没有自定义方法时直接映射数据源的属性。
  • 如果有嵌套的GraphQL类型(比如UserType包含AddressType字段),只要嵌套类型也继承了包含TypeSerializable的BaseObject,to_h会自动递归处理嵌套字段。

内容的提问来源于stack exchange,提问作者nekogami

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 10:12:56