Skip to content

Commit

Permalink
Merge pull request #32 from exAspArk/graphql
Browse files Browse the repository at this point in the history
Make BatchLoader work with the latest GraphQL versions
  • Loading branch information
exAspArk authored Feb 1, 2019
2 parents 5775e52 + 7895379 commit 879cb72
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 28 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,13 +258,13 @@ query = "
Schema.execute(query)
```

To avoid this problem, all we have to do is to change the resolver to return `BatchLoader`:
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`):

```ruby
PostType = GraphQL::ObjectType.define do
name "Post"
field :user, !UserType, resolve: ->(post, args, ctx) do
BatchLoader.for(post.user_id).batch do |user_ids, loader|
BatchLoader::GraphQL.for(post.user_id).batch do |user_ids, loader|
User.where(id: user_ids).each { |user| loader.call(user.id, user) }
end
end
Expand Down
40 changes: 28 additions & 12 deletions lib/batch_loader/graphql.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,45 @@

class BatchLoader
class GraphQL
class Wrapper
def initialize(batch_loader)
@batch_loader = batch_loader
end

def sync
@batch_loader.__sync
end
end

def self.use(schema_definition)
schema_definition.lazy_resolve(BatchLoader::GraphQL::Wrapper, :sync)
schema_definition.lazy_resolve(BatchLoader::GraphQL, :sync)
# for graphql gem versions <= 1.8.6 which work with BatchLoader instead of BatchLoader::GraphQL
schema_definition.instrument(:field, self)
end

def self.instrument(type, field)
old_resolve_proc = field.resolve_proc
new_resolve_proc = ->(object, arguments, context) do
result = old_resolve_proc.call(object, arguments, context)
result.respond_to?(:__sync) ? BatchLoader::GraphQL::Wrapper.new(result) : result
result.respond_to?(:__sync) ? BatchLoader::GraphQL.wrap(result) : result
end

field.redefine { resolve(new_resolve_proc) }
end

def self.wrap(batch_loader)
BatchLoader::GraphQL.new.tap do |graphql|
graphql.batch_loader = batch_loader
end
end

def self.for(item)
new(item)
end

attr_writer :batch_loader

def initialize(item = nil)
@batch_loader = BatchLoader.for(item)
end

def batch(*args, &block)
@batch_loader.batch(*args, &block)
self
end

def sync
@batch_loader.__sync
end
end
end
25 changes: 16 additions & 9 deletions spec/fixtures/graphql_schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,15 @@

PostType = GraphQL::ObjectType.define do
name "Post"
field :user, !UserType, resolve: ->(object, args, ctx) { object.user_lazy }
field :userId, !types.Int, resolve: ->(object, args, ctx) do
BatchLoader.for(object).batch do |posts, loader|
posts.each { |p| loader.call(p, p.user_lazy.id) }
field :user, !UserType, resolve: ->(object, args, ctx) do
BatchLoader::GraphQL.for(object.user_id).batch do |user_ids, loader|
User.where(id: user_ids).each { |user| loader.call(user.id, user) }
end
end

field :userOld, !UserType, resolve: ->(object, args, ctx) do
BatchLoader.for(object.user_id).batch do |user_ids, loader|
User.where(id: user_ids).each { |user| loader.call(user.id, user) }
end
end
end
Expand All @@ -31,15 +36,17 @@ class UserType < GraphQL::Schema::Object

class PostType < GraphQL::Schema::Object
field :user, UserType, null: false
field :user_id, Int, null: false
field :user_old, UserType, null: false

def user
object.user_lazy
BatchLoader::GraphQL.for(object.user_id).batch do |user_ids, loader|
User.where(id: user_ids).each { |user| loader.call(user.id, user) }
end
end

def user_id
BatchLoader.for(object).batch do |posts, loader|
posts.each { |p| loader.call(p, p.user_lazy.id) }
def user_old
BatchLoader.for(object.user_id).batch do |user_ids, loader|
User.where(id: user_ids).each { |user| loader.call(user.id, user) }
end
end
end
Expand Down
1 change: 0 additions & 1 deletion spec/fixtures/models.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ def eql?(other)
private

def some_private_method
:some_private_method
end
end

Expand Down
8 changes: 4 additions & 4 deletions spec/graphql_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@
{
posts {
user { id }
userId
userOld { id }
}
}
QUERY

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

result = GraphqlSchema.execute(query)

expect(result['data']).to eq({
'posts' => [
{'user' => {'id' => "1"}, "userId" => 1},
{'user' => {'id' => "2"}, "userId" => 2}
{'user' => {'id' => "1"}, 'userOld' => {'id' => "1"}},
{'user' => {'id' => "2"}, 'userOld' => {'id' => "2"}}
]
})
end
Expand Down

0 comments on commit 879cb72

Please sign in to comment.