diff --git a/README.md b/README.md index a11a352..231ef38 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,8 @@ A collection of utilities for building GraphQL APIs. - [Installation](#installation) - [Usage](#usage) - [GraphQL::Extras::Controller](#graphqlextrascontroller) - - [GraphQL::Extras::AssociationLoader](#graphqlextrasassociationloader) - [GraphQL::Extras::Preload](#graphqlextraspreload) + - [GraphQL::Extras::PreloadSource](#graphqlextraspreloadsource) - [GraphQL::Extras::Types](#graphqlextrastypes) - [Date](#date) - [DateTime](#datetime) @@ -53,21 +53,15 @@ class GraphqlController < ApplicationController end ``` -### GraphQL::Extras::AssociationLoader - -This is a subclass of [`GraphQL::Batch::Loader`](https://github.com/Shopify/graphql-batch) that performs eager loading of Active Record associations. - -```ruby -loader = GraphQL::Extras::AssociationLoader.for(:blog) -loader.load(Post.first) -loader.load_many(Post.all) -``` - ### GraphQL::Extras::Preload This allows you to preload associations before resolving fields. ```ruby +class Schema < GraphQL::Schema + use GraphQL::Dataloader +end + class BaseField < GraphQL::Schema::Field prepend GraphQL::Extras::Preload end @@ -87,6 +81,16 @@ class PostType < BaseObject end ``` +### GraphQL::Extras::PreloadSource + +This is a subclass of [`GraphQL::Dataloader::Source`](https://graphql-ruby.org/dataloader/overview.html) that performs eager loading of Active Record associations. + +```ruby +loader = dataloader.with(GraphQL::Extras::PreloadSource, :blog) +loader.load(Post.first) +loader.load_many(Post.all) +``` + ### GraphQL::Extras::Types In your base classes, you should include the `GraphQL::Extras::Types`. diff --git a/graphql-extras.gemspec b/graphql-extras.gemspec index f1cf364..a3e102c 100644 --- a/graphql-extras.gemspec +++ b/graphql-extras.gemspec @@ -26,7 +26,6 @@ Gem::Specification.new do |spec| spec.add_dependency "activesupport", ">= 5.2" spec.add_dependency "graphql", "~> 1.12" - spec.add_dependency "graphql-batch", "~> 0.4" spec.add_development_dependency "bundler", "~> 2.0" spec.add_development_dependency "rake", "~> 13.0" diff --git a/lib/graphql/extras.rb b/lib/graphql/extras.rb index 6175887..9fcbf16 100644 --- a/lib/graphql/extras.rb +++ b/lib/graphql/extras.rb @@ -1,7 +1,6 @@ require "graphql/extras/version" require "graphql/extras/types" require "graphql/extras/controller" -require "graphql/extras/association_loader" require "graphql/extras/preload" module GraphQL diff --git a/lib/graphql/extras/association_loader.rb b/lib/graphql/extras/association_loader.rb deleted file mode 100644 index 5544795..0000000 --- a/lib/graphql/extras/association_loader.rb +++ /dev/null @@ -1,24 +0,0 @@ -require "graphql/batch" - -module GraphQL - module Extras - class AssociationLoader < GraphQL::Batch::Loader - def initialize(preload) - @preload = preload - end - - def cache_key(record) - record.object_id - end - - def perform(records) - preloader = ActiveRecord::Associations::Preloader.new - preloader.preload(records, @preload) - - records.each do |record| - fulfill(record, nil) unless fulfilled?(record) - end - end - end - end -end diff --git a/lib/graphql/extras/preload.rb b/lib/graphql/extras/preload.rb index e2f46b1..6bc86ea 100644 --- a/lib/graphql/extras/preload.rb +++ b/lib/graphql/extras/preload.rb @@ -1,7 +1,17 @@ -require "graphql/extras/association_loader" - module GraphQL module Extras + class PreloadSource < GraphQL::Dataloader::Source + def initialize(preload) + @preload = preload + end + + def fetch(records) + preloader = ActiveRecord::Associations::Preloader.new + preloader.preload(records, @preload) + records + end + end + module Preload # @override def initialize(*args, preload: nil, **opts, &block) @@ -10,13 +20,13 @@ def initialize(*args, preload: nil, **opts, &block) end # @override - def resolve(object, args, ctx) - return super unless @preload - - loader = AssociationLoader.for(@preload) - loader.load(object.object).then do - super(object, args, ctx) + def resolve(object, args, context) + if @preload + loader = context.dataloader.with(PreloadSource, @preload) + loader.load(object.object) end + + super end end end diff --git a/spec/graphql/extras/preload_spec.rb b/spec/graphql/extras/preload_spec.rb index 2c7d859..71d78c0 100644 --- a/spec/graphql/extras/preload_spec.rb +++ b/spec/graphql/extras/preload_spec.rb @@ -34,7 +34,7 @@ def bars_batched; Bar.all; end class BatchSchema < GraphQL::Schema query BatchQueryType - use GraphQL::Batch + use GraphQL::Dataloader end before :all do