1
    module Types::ProgramType
        include Types::BaseInterface
    
        description "Objects which inherit from Program"
        graphql_name "Program"
        orphan_types Types::SomeProgramType, Types::AnotherProgramType, Types::ThirdProgramType
    
        field :id, ID, null: false
        field :type, Integer, null: false
        field :name, String, null: false

    definition_methods do
      def self.resolve_type(object, _context)
        case object.class
        when SomeProgram then SomeProgramType
        when AnotherProgram then AnotherProgramType
        when ThirdProgram then ThirdProgramType
        else
          raise "Unknown program type"
        end
      end
    end
    end
    
    module Types
      class SomeProgramType < Types::BaseObject
        implements Types:ProgramType
    
        field :description, String, null: false
      end
    end

I also added queries for SomeProgram types in the query_type file. I was under the impression that adding "implement " to the object types, would allow them to inherit the fields from the interface (per this link: https://graphql-ruby.org/type_definitions/interfaces) and I would be able to query like this:

    query {
            someProgram(id: 1) {
               name
               type
               description
            }
}
     

But I am getting errors in graphiql, like "Field 'name' doesn't exist on type 'SomeProgram'". What am I missing?

Update:

My QueryType class:

class QueryType < Types::BaseObject
    # Add `node(id: ID!) and `nodes(ids: [ID!]!)`
    include GraphQL::Types::Relay::HasNodeField
    include GraphQL::Types::Relay::HasNodesField

    field :some_programs, [SomeProgramType], null: false,
      description: "all some programs"

    def some_programs
      SomeProgram.all
    end

    field :some_program, SomeProgramType, null: false do
      argument :id, ID, required: true
    end

    def some_program(id:)
      SomeProgram.find(id)
    end
end
KSC
  • 78
  • 10

2 Answers2

1

Can you also share how you expose someProgram in your query type?

You can also debug this by looking into the schema if you are using GraphiQL app. You can see the return type of someProgram which should be type of ProgramType.

You can also update your query to include __typename so maybe start with

query {
   someProgram(id: 1) {
       __typename
   }
}
     

First to see what is the return type and if it's being properly handled in the resolve_type

Ashkinas
  • 41
  • 1
  • I added the QueryType above. I tried running your query with typename and now I I'm getting a different error which is much more helpful though still very confusing. "Failed to implement Query.somePrograms, tried:\n\n - `Types::QueryType#some_programs`, which did not exist\n - `NilClass#some_programs`, which did not exist\n - Looking up hash key `:some_programs` or `\"some_programs\"` on ``, but it wasn't a Hash" – KSC Oct 27 '21 at 15:17
  • Messed around with things too much. Fixed it but still can't inherit the fields from the ProgramType interface. Now the the results are: { "data": { "someProgram": { "__typename": "SomeProgram" } } } – KSC Oct 27 '21 at 17:27
  • shouldn't the `__typename` be `SomeProgramType`? i feel like your `resolve_type` is not working as expected. I would put a debug message in `resolve_type` and see where it lands. – Ashkinas Oct 27 '21 at 21:50
0

I figured out the issue. I had put implements Types:SomeProgram instead of implements Types::SomeProgram. I was missing a colon.

KSC
  • 78
  • 10