diff --git a/README.md b/README.md index c75e023..9b75959 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/lib/batch_loader/graphql.rb b/lib/batch_loader/graphql.rb index 5cba1df..27ba42e 100644 --- a/lib/batch_loader/graphql.rb +++ b/lib/batch_loader/graphql.rb @@ -2,18 +2,9 @@ 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 @@ -21,10 +12,35 @@ 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 diff --git a/spec/fixtures/graphql_schema.rb b/spec/fixtures/graphql_schema.rb index 7940b37..bbbfc4d 100644 --- a/spec/fixtures/graphql_schema.rb +++ b/spec/fixtures/graphql_schema.rb @@ -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 @@ -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 diff --git a/spec/fixtures/models.rb b/spec/fixtures/models.rb index 768e3fc..b37c95e 100644 --- a/spec/fixtures/models.rb +++ b/spec/fixtures/models.rb @@ -84,7 +84,6 @@ def eql?(other) private def some_private_method - :some_private_method end end diff --git a/spec/graphql_spec.rb b/spec/graphql_spec.rb index 0e9514a..686b4da 100644 --- a/spec/graphql_spec.rb +++ b/spec/graphql_spec.rb @@ -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