From e8148d84ce500f8f4c155ab1f5bc7a4fb943511d Mon Sep 17 00:00:00 2001 From: exAspArk Date: Tue, 2 Aug 2022 11:20:45 -0400 Subject: [PATCH] Describe how to use a simple `preload:` helper with GraphQL --- README.md | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 45f82ac..9309bf4 100644 --- a/README.md +++ b/README.md @@ -312,7 +312,39 @@ class MyProjectSchema < GraphQL::Schema end ``` -That's it. +--- + +If you need to use BatchLoader with ActiveRecord in multiple places, you can use this `preload:` helper shared by [Aha!](https://www.aha.io/engineering/articles/automatically-avoiding-graphql-n-1s): + +```rb +field :user, UserType, null: false, preload: :user +# ^^^^^^^^^^^^^^ +# Simply add this instead of defining custom `user` method with BatchLoader +``` + +And add this custom field resolver that uses ActiveRecord's preload functionality with BatchLoader: + +```rb +# app/graphql/types/base_object.rb +field_class Types::PreloadableField + +# app/graphql/types/preloadable_field.rb +class Types::PreloadableField < Types::BaseField + def initialize(*args, preload: nil, **kwargs, &block) + @preloads = preload + super(*args, **kwargs, &block) + end + + def resolve(type, args, ctx) + return super unless @preloads + + BatchLoader::GraphQL.for(type).batch(key: self) do |records, loader| + ActiveRecord::Associations::Preloader.new.preload(records.map(&:object), @preloads) + records.each { |r| loader.call(r, super(r, args, ctx)) } + end + end +end +``` ### Loading multiple items