使用 graphql-ruby 实现联合类型

Posted

技术标签:

【中文标题】使用 graphql-ruby 实现联合类型【英文标题】:Implementing union type with graphql-ruby 【发布时间】:2020-02-09 13:30:43 【问题描述】:

我正在尝试使用graphql-ruby 实现联合类型。

我关注了official documentation,但得到了下面列出的错误。

这是我当前的代码。

module Types
  class AudioClipType < Types::BaseObject
    field :id, Int, null: false
    field :duration, Int, null: false
  end
end

module Types
  class MovieClipType < Types::BaseObject
    field :id, Int, null: false
    field :previewURL, String, null: false
    field :resolution, Int, null: false
  end
end

module Types
  class MediaItemType < Types::BaseUnion
    possible_types Types::AudioClipType, Types::MovieClipType

    def self.resolve_type(object, context)
      if object.is_a?(AudioClip)
        Types::AudioClipType
      else
        Types::MovieClipType
      end
    end
  end
end

module Types
  class PostType < Types::BaseObject
    description 'Post'
    field :id, Int, null: false
    field :media_item, Types::MediaItemType, null: true
  end
end

这里是 graphql 查询。


  posts 
    id
    mediaItem 
      __typename
      ... on AudioClip 
        id
        duration
      
      ... on MovieClip 
        id
        previewURL
        resolution
      
    
  

当我发送查询时,出现以下错误。

Failed to implement Post.mediaItem, tried:
 - `Types::PostType#media_item`, which did not exist
 - `Post#media_item`, which did not exist
 - Looking up hash key `:media_item` or `"media_item"` on `#<Post:0x007fb385769428>`, but it wasn't a Hash

To implement this field, define one of the methods above (and check for typos

找不到任何错别字或任何东西。

我错过了什么吗??

【问题讨论】:

如果我没记错的话,您在 PostType 中定义了一个名为 media_item 的方法,它返回混合对象类型(如音频/电影等),对吗? 【参考方案1】:

您没有定义父类型(联合的超类)。

所以添加

class Types::BaseUnion < GraphQL::Schema::Union
end

现在您的继承链将保持一致。

【讨论】:

以上是关于使用 graphql-ruby 实现联合类型的主要内容,如果未能解决你的问题,请参考以下文章

TypeError:无法读取未定义的属性“类型”

如何使用 graphql-ruby 测试 GraphQL 模式?

graphql-ruby:Int 不是定义的输入类型(在 $first 上)

无法使用 graphql-ruby 订阅进行简单广播

无法理解使用带有 graphql-ruby gem 的 ActionCable 的 GraphQL 订阅

TypeScript 类使用联合类型字段实现接口导致错误 (2322)