Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion lib/graphql/schema/addition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,9 @@ def add_type(type, owner:, late_types:, path:)
# We can get these now; we'll have to get late-bound types later
if interface_type.is_a?(Module) && type.is_a?(Class)
implementers = @possible_types[interface_type] ||= []
implementers << type
if !implementers.include?(type)
implementers << type
end
end
when String, Schema::LateBoundType
interface_type = interface_type_membership
Expand Down
19 changes: 11 additions & 8 deletions lib/graphql/schema/visibility.rb
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,11 @@ def ensure_all_loaded(types_to_visit)
def load_all(types: nil)
if @visit.nil?
# Set up the visit system
@interface_type_memberships = Hash.new { |h, interface_type| h[interface_type] = [] }.compare_by_identity
@interface_type_memberships = Hash.new { |h, interface_type|
h[interface_type] = Hash.new { |h2, obj_type|
h2[obj_type] = []
}.compare_by_identity
}.compare_by_identity
@directives = []
@types = {} # String => Module
@all_references = Hash.new { |h, member| h[member] = Set.new.compare_by_identity }.compare_by_identity
Expand All @@ -237,7 +241,7 @@ def load_all(types: nil)
@all_references[itm.abstract_type] << member
# `itm.object_type` may not actually be `member` if this implementation
# is inherited from a superclass
@interface_type_memberships[itm.abstract_type] << [itm, member]
@interface_type_memberships[itm.abstract_type][member] << itm
end
elsif member < GraphQL::Schema::Union
@unions_for_references << member
Expand Down Expand Up @@ -286,12 +290,11 @@ def load_all(types: nil)

# TODO: somehow don't iterate over all these,
# only the ones that may have been modified
@interface_type_memberships.each do |int_type, type_membership_pairs|
referers = @all_references[int_type].select { |r| r.is_a?(GraphQL::Schema::Field) }
if !referers.empty?
type_membership_pairs.each do |(type_membership, impl_type)|
# Add new items only:
@all_references[impl_type] |= referers
@interface_type_memberships.each do |int_type, obj_type_memberships|
referrers = @all_references[int_type].select { |r| r.is_a?(GraphQL::Schema::Field) }
if !referrers.empty?
obj_type_memberships.each_key do |impl_type|
@all_references[impl_type] |= referrers
end
end
end
Expand Down
8 changes: 5 additions & 3 deletions lib/graphql/schema/visibility/profile.rb
Original file line number Diff line number Diff line change
Expand Up @@ -403,9 +403,11 @@ def possible_types_for(type)
case type.kind.name
when "INTERFACE"
pts = []
@visibility.all_interface_type_memberships[type].each do |(itm, impl_type)|
if @cached_visible[itm] && @cached_visible[impl_type] && referenced?(impl_type)
pts << impl_type
@visibility.all_interface_type_memberships[type].each do |impl_type, type_memberships|
if impl_type.kind.object? && referenced?(impl_type) && @cached_visible[impl_type]
if type_memberships.any? { |itm| @cached_visible[itm] }
pts << impl_type
end
end
end
pts
Expand Down
5 changes: 5 additions & 0 deletions spec/graphql/schema/interface_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,11 @@ def thing

assert_equal ["Named", "Node", "Timestamped"], interfaces_names
end

it "doesn't return interfaces as possible types" do
pts = TransitiveInterfaceSchema.possible_types(TransitiveInterfaceSchema::Node)
assert_equal ["Thing"], pts.map(&:graphql_name)
end
end

describe "supplying a fallback_value to a field" do
Expand Down