Skip to content

Commit 879cb72

Browse files
authored
Merge pull request #32 from exAspArk/graphql
Make BatchLoader work with the latest GraphQL versions
2 parents 5775e52 + 7895379 commit 879cb72

File tree

5 files changed

+50
-28
lines changed

5 files changed

+50
-28
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,13 +258,13 @@ query = "
258258
Schema.execute(query)
259259
```
260260

261-
To avoid this problem, all we have to do is to change the resolver to return `BatchLoader`:
261+
To avoid this problem, all we have to do is to change the resolver to return `BatchLoader::GraphQL` ([#32](https://github.com/exAspArk/batch-loader/pull/32) explains why not just `BatchLoader`):
262262

263263
```ruby
264264
PostType = GraphQL::ObjectType.define do
265265
name "Post"
266266
field :user, !UserType, resolve: ->(post, args, ctx) do
267-
BatchLoader.for(post.user_id).batch do |user_ids, loader|
267+
BatchLoader::GraphQL.for(post.user_id).batch do |user_ids, loader|
268268
User.where(id: user_ids).each { |user| loader.call(user.id, user) }
269269
end
270270
end

lib/batch_loader/graphql.rb

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,45 @@
22

33
class BatchLoader
44
class GraphQL
5-
class Wrapper
6-
def initialize(batch_loader)
7-
@batch_loader = batch_loader
8-
end
9-
10-
def sync
11-
@batch_loader.__sync
12-
end
13-
end
14-
155
def self.use(schema_definition)
16-
schema_definition.lazy_resolve(BatchLoader::GraphQL::Wrapper, :sync)
6+
schema_definition.lazy_resolve(BatchLoader::GraphQL, :sync)
7+
# for graphql gem versions <= 1.8.6 which work with BatchLoader instead of BatchLoader::GraphQL
178
schema_definition.instrument(:field, self)
189
end
1910

2011
def self.instrument(type, field)
2112
old_resolve_proc = field.resolve_proc
2213
new_resolve_proc = ->(object, arguments, context) do
2314
result = old_resolve_proc.call(object, arguments, context)
24-
result.respond_to?(:__sync) ? BatchLoader::GraphQL::Wrapper.new(result) : result
15+
result.respond_to?(:__sync) ? BatchLoader::GraphQL.wrap(result) : result
2516
end
2617

2718
field.redefine { resolve(new_resolve_proc) }
2819
end
20+
21+
def self.wrap(batch_loader)
22+
BatchLoader::GraphQL.new.tap do |graphql|
23+
graphql.batch_loader = batch_loader
24+
end
25+
end
26+
27+
def self.for(item)
28+
new(item)
29+
end
30+
31+
attr_writer :batch_loader
32+
33+
def initialize(item = nil)
34+
@batch_loader = BatchLoader.for(item)
35+
end
36+
37+
def batch(*args, &block)
38+
@batch_loader.batch(*args, &block)
39+
self
40+
end
41+
42+
def sync
43+
@batch_loader.__sync
44+
end
2945
end
3046
end

spec/fixtures/graphql_schema.rb

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,15 @@
77

88
PostType = GraphQL::ObjectType.define do
99
name "Post"
10-
field :user, !UserType, resolve: ->(object, args, ctx) { object.user_lazy }
11-
field :userId, !types.Int, resolve: ->(object, args, ctx) do
12-
BatchLoader.for(object).batch do |posts, loader|
13-
posts.each { |p| loader.call(p, p.user_lazy.id) }
10+
field :user, !UserType, resolve: ->(object, args, ctx) do
11+
BatchLoader::GraphQL.for(object.user_id).batch do |user_ids, loader|
12+
User.where(id: user_ids).each { |user| loader.call(user.id, user) }
13+
end
14+
end
15+
16+
field :userOld, !UserType, resolve: ->(object, args, ctx) do
17+
BatchLoader.for(object.user_id).batch do |user_ids, loader|
18+
User.where(id: user_ids).each { |user| loader.call(user.id, user) }
1419
end
1520
end
1621
end
@@ -31,15 +36,17 @@ class UserType < GraphQL::Schema::Object
3136

3237
class PostType < GraphQL::Schema::Object
3338
field :user, UserType, null: false
34-
field :user_id, Int, null: false
39+
field :user_old, UserType, null: false
3540

3641
def user
37-
object.user_lazy
42+
BatchLoader::GraphQL.for(object.user_id).batch do |user_ids, loader|
43+
User.where(id: user_ids).each { |user| loader.call(user.id, user) }
44+
end
3845
end
3946

40-
def user_id
41-
BatchLoader.for(object).batch do |posts, loader|
42-
posts.each { |p| loader.call(p, p.user_lazy.id) }
47+
def user_old
48+
BatchLoader.for(object.user_id).batch do |user_ids, loader|
49+
User.where(id: user_ids).each { |user| loader.call(user.id, user) }
4350
end
4451
end
4552
end

spec/fixtures/models.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ def eql?(other)
8484
private
8585

8686
def some_private_method
87-
:some_private_method
8887
end
8988
end
9089

spec/graphql_spec.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,19 @@
1010
{
1111
posts {
1212
user { id }
13-
userId
13+
userOld { id }
1414
}
1515
}
1616
QUERY
1717

18-
expect(User).to receive(:where).with(id: ["1", "2"]).once.and_call_original
18+
expect(User).to receive(:where).with(id: ["1", "2"]).twice.and_call_original
1919

2020
result = GraphqlSchema.execute(query)
2121

2222
expect(result['data']).to eq({
2323
'posts' => [
24-
{'user' => {'id' => "1"}, "userId" => 1},
25-
{'user' => {'id' => "2"}, "userId" => 2}
24+
{'user' => {'id' => "1"}, 'userOld' => {'id' => "1"}},
25+
{'user' => {'id' => "2"}, 'userOld' => {'id' => "2"}}
2626
]
2727
})
2828
end

0 commit comments

Comments
 (0)