Graphql-ruby: Class inheritance stop working for `implements GraphQL::Types::Relay::Node`

Created on 12 Apr 2020  路  4Comments  路  Source: rmosolgo/graphql-ruby

For inheritance type classes structure, f.e.

class Types::UserType < Types::BaseObject
...
end

class Types::BaseObject < GraphQL::Schema::Object
  implements GraphQL::Relay::Node.interface
  # or implements GraphQL::Types::Relay::Node
end

Types::UserType doesn't available for node/nodes query, but it was in version 1.10.5

Is it expected changes or something went wrong?

graphql version: 1.10.6

Most helpful comment

Hmm, I'm not sure _why_ this is the problem, but I worked with your example and found that updating the implements call fixed it:

+   implements GraphQL::Types::Relay::Node
-   implements GraphQL::Relay::Node.interface

(doc)

Does that work for you?

Here's the full script that worked for me:

require 'bundler/inline'

gemfile do
  source 'https://rubygems.org'
  gem 'graphql', '1.10.7'
end

module Types
end

class Types::BaseObject < GraphQL::Schema::Object
  implements GraphQL::Types::Relay::Node
end

class Types::UserType < Types::BaseObject
  global_id_field :id
end


class Types::QueryType < Types::BaseObject
  add_field(GraphQL::Types::Relay::NodeField)
  field :user, Types::UserType, null: true
end

class Schema < GraphQL::Schema
  query(Types::QueryType)

  use(GraphQL::Execution::Interpreter)
  use(GraphQL::Analysis::AST)

  def self.object_from_id(id, ctx)
    { id: id }
  end

  def self.id_from_object(obj, type, ctx)
    obj[:id]
  end

  def self.resolve_type(abs_type, obj, ctx)
    Types::UserType
  end
end

pp Schema.execute(<<~GRAPHQL).to_h
{
  node(id: "123") {
    ... on User {
      id
    }
  }
}
GRAPHQL
# => {"data"=>{"node"=>{"id"=>"123"}}}

All 4 comments

Oh, thanks for the heads up! I must have broke this during #2791. I'll look for a fix.

I'm not sure that #2882 really fixes this issue. 1.10.7 doesn't fix the inheritance problem with my implementation (working fine with 1.10.5), which seems to be the same than the one described here.

class Types::UserType < Types::BaseObject
  global_id_field :id
end

class Types::BaseObject < GraphQL::Schema::Object
  implements GraphQL::Relay::Node.interface
end

class Types::QueryType < Types::BaseObject
  add_field(GraphQL::Types::Relay::NodeField)
end

I have the following error message when querying on a _User_ node:

Field 'node' doesn't exist on type 'Query'

Hmm, I'm not sure _why_ this is the problem, but I worked with your example and found that updating the implements call fixed it:

+   implements GraphQL::Types::Relay::Node
-   implements GraphQL::Relay::Node.interface

(doc)

Does that work for you?

Here's the full script that worked for me:

require 'bundler/inline'

gemfile do
  source 'https://rubygems.org'
  gem 'graphql', '1.10.7'
end

module Types
end

class Types::BaseObject < GraphQL::Schema::Object
  implements GraphQL::Types::Relay::Node
end

class Types::UserType < Types::BaseObject
  global_id_field :id
end


class Types::QueryType < Types::BaseObject
  add_field(GraphQL::Types::Relay::NodeField)
  field :user, Types::UserType, null: true
end

class Schema < GraphQL::Schema
  query(Types::QueryType)

  use(GraphQL::Execution::Interpreter)
  use(GraphQL::Analysis::AST)

  def self.object_from_id(id, ctx)
    { id: id }
  end

  def self.id_from_object(obj, type, ctx)
    obj[:id]
  end

  def self.resolve_type(abs_type, obj, ctx)
    Types::UserType
  end
end

pp Schema.execute(<<~GRAPHQL).to_h
{
  node(id: "123") {
    ... on User {
      id
    }
  }
}
GRAPHQL
# => {"data"=>{"node"=>{"id"=>"123"}}}

@rmosolgo thanks a lot, indeed this change fixes it!

+   implements GraphQL::Types::Relay::Node
-   implements GraphQL::Relay::Node.interface

I did some research to understand how I could have come up with my implementation, since the current documentation points to the correct syntax 馃槄 .
It seems it was recently corrected in 146b9652d6e49b20e09c23a598430656df775eec (see #2724) and if I'm reading correctly, the "broken" version is the _old-style_ interface, vs the correct _new-style_ one. So I guess we should migrate now to the _new-style_ 馃槑

Was this page helpful?
0 / 5 - 0 ratings