Skip to content

Commit 5069859

Browse files
authored
Merge pull request #5395 from rmosolgo/possible-types-without-interfaces
Don't return other interfaces in list of .possible_types
2 parents e65f537 + bbda131 commit 5069859

File tree

4 files changed

+24
-12
lines changed

4 files changed

+24
-12
lines changed

lib/graphql/schema/addition.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,9 @@ def add_type(type, owner:, late_types:, path:)
258258
# We can get these now; we'll have to get late-bound types later
259259
if interface_type.is_a?(Module) && type.is_a?(Class)
260260
implementers = @possible_types[interface_type] ||= []
261-
implementers << type
261+
if !implementers.include?(type)
262+
implementers << type
263+
end
262264
end
263265
when String, Schema::LateBoundType
264266
interface_type = interface_type_membership

lib/graphql/schema/visibility.rb

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,11 @@ def ensure_all_loaded(types_to_visit)
212212
def load_all(types: nil)
213213
if @visit.nil?
214214
# Set up the visit system
215-
@interface_type_memberships = Hash.new { |h, interface_type| h[interface_type] = [] }.compare_by_identity
215+
@interface_type_memberships = Hash.new { |h, interface_type|
216+
h[interface_type] = Hash.new { |h2, obj_type|
217+
h2[obj_type] = []
218+
}.compare_by_identity
219+
}.compare_by_identity
216220
@directives = []
217221
@types = {} # String => Module
218222
@all_references = Hash.new { |h, member| h[member] = Set.new.compare_by_identity }.compare_by_identity
@@ -237,7 +241,7 @@ def load_all(types: nil)
237241
@all_references[itm.abstract_type] << member
238242
# `itm.object_type` may not actually be `member` if this implementation
239243
# is inherited from a superclass
240-
@interface_type_memberships[itm.abstract_type] << [itm, member]
244+
@interface_type_memberships[itm.abstract_type][member] << itm
241245
end
242246
elsif member < GraphQL::Schema::Union
243247
@unions_for_references << member
@@ -286,12 +290,11 @@ def load_all(types: nil)
286290

287291
# TODO: somehow don't iterate over all these,
288292
# only the ones that may have been modified
289-
@interface_type_memberships.each do |int_type, type_membership_pairs|
290-
referers = @all_references[int_type].select { |r| r.is_a?(GraphQL::Schema::Field) }
291-
if !referers.empty?
292-
type_membership_pairs.each do |(type_membership, impl_type)|
293-
# Add new items only:
294-
@all_references[impl_type] |= referers
293+
@interface_type_memberships.each do |int_type, obj_type_memberships|
294+
referrers = @all_references[int_type].select { |r| r.is_a?(GraphQL::Schema::Field) }
295+
if !referrers.empty?
296+
obj_type_memberships.each_key do |impl_type|
297+
@all_references[impl_type] |= referrers
295298
end
296299
end
297300
end

lib/graphql/schema/visibility/profile.rb

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -403,9 +403,11 @@ def possible_types_for(type)
403403
case type.kind.name
404404
when "INTERFACE"
405405
pts = []
406-
@visibility.all_interface_type_memberships[type].each do |(itm, impl_type)|
407-
if @cached_visible[itm] && @cached_visible[impl_type] && referenced?(impl_type)
408-
pts << impl_type
406+
@visibility.all_interface_type_memberships[type].each do |impl_type, type_memberships|
407+
if impl_type.kind.object? && referenced?(impl_type) && @cached_visible[impl_type]
408+
if type_memberships.any? { |itm| @cached_visible[itm] }
409+
pts << impl_type
410+
end
409411
end
410412
end
411413
pts

spec/graphql/schema/interface_spec.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,11 @@ def thing
359359

360360
assert_equal ["Named", "Node", "Timestamped"], interfaces_names
361361
end
362+
363+
it "doesn't return interfaces as possible types" do
364+
pts = TransitiveInterfaceSchema.possible_types(TransitiveInterfaceSchema::Node)
365+
assert_equal ["Thing"], pts.map(&:graphql_name)
366+
end
362367
end
363368

364369
describe "supplying a fallback_value to a field" do

0 commit comments

Comments
 (0)