lib/graphql/relay/connection_resolve.rb in graphql-1.5.13 vs lib/graphql/relay/connection_resolve.rb in graphql-1.5.14
- old
+ new
@@ -1,24 +1,36 @@
# frozen_string_literal: true
module GraphQL
module Relay
class ConnectionResolve
- def initialize(field, underlying_resolve)
+ def initialize(field, underlying_resolve, lazy:)
@field = field
@underlying_resolve = underlying_resolve
@max_page_size = field.connection_max_page_size
+ @lazy = lazy
end
def call(obj, args, ctx)
+ if @lazy && obj.is_a?(LazyNodesWrapper)
+ parent = obj.parent
+ obj = obj.lazy_object
+ else
+ parent = obj
+ end
+
nodes = @underlying_resolve.call(obj, args, ctx)
if nodes.nil?
nil
elsif ctx.schema.lazy?(nodes)
- nodes
+ if !@lazy
+ LazyNodesWrapper.new(obj, nodes)
+ else
+ nodes
+ end
else
- build_connection(nodes, args, obj, ctx)
+ build_connection(nodes, args, parent, ctx)
end
end
private
@@ -29,8 +41,18 @@
else
connection_class = GraphQL::Relay::BaseConnection.connection_for_nodes(nodes)
connection_class.new(nodes, args, field: @field, max_page_size: @max_page_size, parent: parent, context: ctx)
end
end
+
+ # A container for the proper `parent` of connection nodes.
+ # Without this wrapper, the lazy object _itself_ is passed into `build_connection`
+ # and it becomes the parent, which is wrong.
+ #
+ # We can get away with it because we know that this instrumentation will be applied last.
+ # That means its code after `underlying_resolve` will be _last_ on the way in.
+ # And, its code before `underlying_resolve` will be _first_ during lazy resolution.
+ # @api private
+ LazyNodesWrapper = Struct.new(:parent, :lazy_object)
end
end
end