graphql-batch
graphql-batch copied to clipboard
Does not seem to work with unions
The resolve_type seems to get the promise rather than the solved value:
Target = GraphQL::UnionType.define do
name 'MyTarget'
possible_types [X::Type, Y::Type]
resolve_type ->(obj, _ctx) do
binding.pry # -> obj.class == GraphQL::Batch::Promise
case o
when X then X::Type
when Y then Y::Type
end
end
end
Type = GraphQL::ObjectType.define do
name 'MyType'
field :id, !GraphQL::Common::ObjectId
field :targets, !types[!Target] do
resolve ->(obj, _args, _ctx) do
case obj.target_type
when 'X' then obj.targets.map { |t| RecordLoader.for(X).load(t) }
when 'Y' then obj.targets.map { |t| RecordLoader.for(Y).load(t) }
end
end
end
I tried to reproduce the issue with the following script
require 'graphql/batch'
class EchoLoader < GraphQL::Batch::Loader
def perform(keys)
keys.each { |key| fulfill(key, key) }
end
end
class IntegerWrapperType < GraphQL::Schema::Object
graphql_name "IntegerWrapper"
field :num, Integer, null: false
def num
object
end
end
class FloatWrapperType < GraphQL::Schema::Object
graphql_name "FloatWrapper"
field :num, Float, null: false
def num
object
end
end
class NumberWrapperType < GraphQL::Schema::Union
graphql_name "NumberWrapper"
possible_types IntegerWrapperType, FloatWrapperType
def self.resolve_type(object, context)
case object
when Integer
IntegerWrapperType
when Float
FloatWrapperType
else
raise TypeError, "unexpected type #{object.class}"
end
end
end
class QueryType < GraphQL::Schema::Object
graphql_name "Query"
field :test, [NumberWrapperType], null: false
def test
[1, 2.0, 3].map { |num| EchoLoader.load(num) }
end
end
class Schema < GraphQL::Schema
query QueryType
use GraphQL::Batch
end
query = '{
test { ... on IntegerWrapper { num }, ... on FloatWrapper { num } }
}'
puts Schema.execute(query, variables: {}).to_h
but it works as expected and outputs
{"data"=>{"test"=>[{"num"=>1}, {"num"=>2.0}, {"num"=>3}]}}
Could you provide a complete script to reproduce the issue? Are you able to reproduce the issue with the latest version of the graphql gem?
Hmm, i'll try to take a look at your code tomorrow probably.
If someone gets here by searching in Google I solved like this
In my Activity model, I have a polymorphic association called trackable.
module Types
module Activities
class ActivityType < Types::BaseModel
field :action, String, null: false
field :trackable, Types::Unions::TrackableUnion, null: false
field :time_ago, String, null: false
field :user, Types::Users::UserType
field :organization, Types::Organizations::OrganizationType
def user
Loaders::RecordLoader.for(User).load(object.user_id)
end
def trackable
case object.trackable_type
when 'Question' then Loaders::RecordLoader.for(Question).load(object.trackable_id)
when 'Video' then Loaders::RecordLoader.for(Question).load(object.trackable_id)
when 'Course' then Loaders::RecordLoader.for(Course).load(object.trackable_id)
end
end
end
end
end
module Types
module Unions
class TrackableUnion < Types::BaseUnion
description 'Activity trackable models'
possible_types Types::Questions::QuestionType, Types::Videos::VideoType, Types::Courses::CourseType
def self.resolve_type(object, _context)
if object.is_a?(Question)
Types::Questions::QuestionType
elsif object.is_a?(Video)
Types::Videos::VideoType
elsif object.is_a?(Course)
Types::Courses::CourseType
end
end
end
end
end