Skip to content

Commit 0afa241

Browse files
authored
Merge pull request #5236 from rmosolgo/vis-superclass-fix
Fix possible_type membership when inherited from superclass
2 parents 199a397 + b71f5f8 commit 0afa241

File tree

3 files changed

+45
-8
lines changed

3 files changed

+45
-8
lines changed

Diff for: lib/graphql/schema/visibility.rb

+6-5
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,9 @@ def load_all(types: nil)
226226
elsif member.respond_to?(:interface_type_memberships)
227227
member.interface_type_memberships.each do |itm|
228228
@all_references[itm.abstract_type] << member
229-
@interface_type_memberships[itm.abstract_type] << itm
229+
# `itm.object_type` may not actually be `member` if this implementation
230+
# is inherited from a superclass
231+
@interface_type_memberships[itm.abstract_type] << [itm, member]
230232
end
231233
elsif member < GraphQL::Schema::Union
232234
@unions_for_references << member
@@ -275,13 +277,12 @@ def load_all(types: nil)
275277

276278
# TODO: somehow don't iterate over all these,
277279
# only the ones that may have been modified
278-
@interface_type_memberships.each do |int_type, type_memberships|
280+
@interface_type_memberships.each do |int_type, type_membership_pairs|
279281
referers = @all_references[int_type].select { |r| r.is_a?(GraphQL::Schema::Field) }
280282
if !referers.empty?
281-
type_memberships.each do |type_membership|
282-
implementor_type = type_membership.object_type
283+
type_membership_pairs.each do |(type_membership, impl_type)|
283284
# Add new items only:
284-
@all_references[implementor_type] |= referers
285+
@all_references[impl_type] |= referers
285286
end
286287
end
287288
end

Diff for: lib/graphql/schema/visibility/profile.rb

+3-3
Original file line numberDiff line numberDiff line change
@@ -319,9 +319,9 @@ def possible_types_for(type)
319319
case type.kind.name
320320
when "INTERFACE"
321321
pts = []
322-
@schema.visibility.all_interface_type_memberships[type].each do |itm|
323-
if @cached_visible[itm] && (ot = itm.object_type) && @cached_visible[ot] && referenced?(ot)
324-
pts << ot
322+
@schema.visibility.all_interface_type_memberships[type].each do |(itm, impl_type)|
323+
if @cached_visible[itm] && @cached_visible[impl_type] && referenced?(impl_type)
324+
pts << impl_type
325325
end
326326
end
327327
pts

Diff for: spec/graphql/schema/visibility_spec.rb

+36
Original file line numberDiff line numberDiff line change
@@ -235,4 +235,40 @@ class OrphanType < GraphQL::Schema::Object
235235
assert_equal [], LazyLoadingSchema::OrphanType.all_field_definitions.first.extensions.map(&:class)
236236
end
237237
end
238+
239+
describe "interfaces thru superclass" do
240+
class InterfaceSuperclassSchema < GraphQL::Schema
241+
module Node
242+
include GraphQL::Schema::Interface
243+
field :id, ID
244+
end
245+
246+
class NodeObject < GraphQL::Schema::Object
247+
implements Node
248+
end
249+
250+
class Thing < NodeObject
251+
field :name, String
252+
end
253+
254+
class Query < GraphQL::Schema::Object
255+
field :node, Node
256+
257+
def node
258+
{ id: "101", name: "Hat" }
259+
end
260+
261+
field :thing, Thing
262+
end
263+
264+
query(Query)
265+
def self.resolve_type(...); Thing; end
266+
use GraphQL::Schema::Visibility
267+
end
268+
end
269+
270+
it "Can use interface relationship properly" do
271+
res = InterfaceSuperclassSchema.execute("{ node { id ... on Thing { name } } }")
272+
assert_equal "Hat", res["data"]["node"]["name"]
273+
end
238274
end

0 commit comments

Comments
 (0)