Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I specify polymorphic types with graphql-ruby?

I have a UserType and a userable that can be a Writer or Account.

For GraphQL I figured maybe I could use a UserableUnion like this:

UserableUnion = GraphQL::UnionType.define do
  name "Userable"
  description "Account or Writer object"
  possible_types [WriterType, AccountType]
end

and then define my UserType like this:

UserType = GraphQL::ObjectType.define do
  name "User"
  description "A user object"
  field :id, !types.ID
  field :userable, UserableUnion
end

But I get schema contains Interfaces or Unions, so you must define a 'resolve_type (obj, ctx) -> { ... }' function

I have tried putting a resolve_type in multiple places, but I can't seem to figure this out?

Does any one now how to implement this?

like image 761
mharris7190 Avatar asked Nov 11 '16 05:11

mharris7190


People also ask

What is polymorphic Ruby?

In Ruby on Rails, a polymorphic association is an Active Record association that can connect a model to multiple other models. For example, we can use a single association to connect the Review model with the Event and Restaurant models, allowing us to connect a review with either an event or a restaurant.

What is type name in GraphQL?

The __typename field returns the object type's name as a String (e.g., Book or Author ). GraphQL clients use an object's __typename for many purposes, such as to determine which type was returned by a field that can return multiple types (i.e., a union or interface).

What is a union type in GraphQL?

Unions and interfaces are abstract GraphQL types that enable a schema field to return one of multiple object types.


2 Answers

That error means you need to define the resolve_type method in your app schema. It should accept an ActiveRecord model and the context, and return a GraphQL type.

AppSchema = GraphQL::Schema.define do
  resolve_type ->(record, ctx) do
    # figure out the GraphQL type from the record (activerecord)
  end
end

You could either implement this example which links a model to a type. Or you could create a class method or attribute on your models that refer to their types. e.g.

class ApplicationRecord < ActiveRecord::Base
  class << self
    attr_accessor :graph_ql_type
  end
end

class Writer < ApplicationRecord
  self.graph_ql_type = WriterType
end

AppSchema = GraphQL::Schema.define do
  resolve_type ->(record, ctx) { record.class.graph_ql_type }
end
like image 126
Marc Greenstock Avatar answered Sep 21 '22 15:09

Marc Greenstock


Now there is UnionType in GraphQL Ruby

https://graphql-ruby.org/type_definitions/unions.html#defining-union-types

It has clear example how define UnionType that you can use.

class Types::CommentSubject < Types::BaseUnion
  description "Objects which may be commented on"
  possible_types Types::Post, Types::Image

  # Optional: if this method is defined, it will override `Schema.resolve_type`
  def self.resolve_type(object, context)
    if object.is_a?(BlogPost)
      Types::Post
    else
      Types::Image
    end
  end
end
like image 40
BlueConga Avatar answered Sep 17 '22 15:09

BlueConga