Skip to content
This repository was archived by the owner on Oct 26, 2022. It is now read-only.

Commit d948a42

Browse files
committed
Restore relation connection with original nodes
1 parent 9618cab commit d948a42

File tree

5 files changed

+40
-11
lines changed

5 files changed

+40
-11
lines changed

lib/graphql/cache/resolvers/connection_resolver.rb

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,17 @@ module Resolvers
66
# Pass cache write method into GraphQL::Relay::BaseConnection
77
# and wrap them original Connection methods
88
class ConnectionResolver < BaseResolver
9-
class ConnectionCache < Module
9+
NodesCache = Struct.new(:nodes, :paged_nodes)
10+
11+
class RelationConnectionOverload < Module
1012
module WrappedMethods
1113
def paged_nodes
1214
cache_write = instance_variable_get(:@__cache_write)
1315

14-
cache_write.call { super }
16+
super.tap do |result|
17+
# save original relation (aka @nodes) and loaded records
18+
cache_write.call { NodesCache.new(@nodes, result) }
19+
end
1520
end
1621
end
1722

@@ -27,26 +32,43 @@ def extended(base)
2732

2833
def call(args:, field:, parent:, context:, force_cache:)
2934
if force_cache || (cached = read).nil?
30-
define_connection_cache(resolve_proc.call)
35+
define_relation_cache(resolve_proc.call)
3136
else
3237
wrap_connection(cached, args, field, parent: parent, context: context)
3338
end
3439
end
3540

3641
private
3742

38-
def wrap_connection(value, args, field, **kwargs)
39-
GraphQL::Relay::BaseConnection.connection_for_nodes(value).new(
40-
value,
43+
def wrap_connection(cached, args, field, **kwargs)
44+
nodes, paged_nodes = parse(cached)
45+
46+
GraphQL::Relay::BaseConnection.connection_for_nodes(nodes).new(
47+
nodes,
4148
args,
4249
field: field,
4350
parent: kwargs[:parent],
4451
context: kwargs[:context]
45-
)
52+
).tap do |connection|
53+
# restore cached paged_nodes
54+
connection.instance_variable_set(:@paged_nodes, paged_nodes) if paged_nodes
55+
end
56+
end
57+
58+
def define_relation_cache(connection)
59+
if connection.is_a?(GraphQL::Relay::RelationConnection)
60+
# inject cached logic into the relation connection
61+
connection.extend(RelationConnectionOverload.new(method(:write)))
62+
else
63+
# cache loaded connection (works for ArrayConnection)
64+
write { connection }
65+
end
4666
end
4767

48-
def define_connection_cache(connection)
49-
connection.extend(ConnectionCache.new(method(:write)))
68+
def parse(cached)
69+
return [cached, nil] unless cached.is_a?(NodesCache)
70+
71+
[cached.nodes, cached.paged_nodes]
5072
end
5173
end
5274
end

spec/features/connections_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ def execute(query, context = {})
105105
<<~SQL
106106
SELECT \"customers\".* FROM \"customers\" ORDER BY \"customers\".\"id\" DESC LIMIT ?\e[0m [[\"LIMIT\", 1]]
107107
SELECT \"customers\".* FROM \"customers\" WHERE \"customers\".\"id\" = ? LIMIT ?\e[0m [[\"id\", 1], [\"LIMIT\", 1]]
108-
SELECT \"orders\".* FROM \"orders\" WHERE \"orders\".\"customer_id\" = ?\e[0m [[\"customer_id\", 1]]
108+
SELECT \"orders\".* FROM \"orders\" WHERE \"orders\".\"customer_id\" = ? LIMIT ?\e[0m [[\"customer_id\", 1], [\"LIMIT\", 50]]
109109
SQL
110110
)
111111
end

spec/spec_helper.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
require 'active_record' # should be required before graphql-ruby
1+
# ORMs should be required before graphql-ruby
2+
require 'active_record'
3+
require 'sequel'
4+
25
require 'bundler/setup'
36
require 'pry'
47

test_schema/active_record/graphql_schema.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ class CacheSchema < ::CacheSchema
1616
query AR::QueryType
1717
use GraphQL::Cache
1818

19+
default_max_page_size 50
20+
1921
def self.resolve_type(_type, obj, _ctx)
2022
"AR::#{obj.class.name}Type"
2123
end

test_schema/sequel/graphql_schema.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ class CacheSchema < GraphQL::Schema
3131

3232
use GraphQL::Cache
3333

34+
default_max_page_size 50
35+
3436
def self.resolve_type(_type, obj, _ctx)
3537
"#{obj.class.name}Type"
3638
end

0 commit comments

Comments
 (0)