README.md in batch-loader-2.0.1 vs README.md in batch-loader-2.0.2

- old
+ new

@@ -1,8 +1,7 @@ # BatchLoader -[![Build Status](https://travis-ci.org/exAspArk/batch-loader.svg?branch=master)](https://travis-ci.org/exAspArk/batch-loader) [![Coverage Status](https://coveralls.io/repos/github/exAspArk/batch-loader/badge.svg)](https://coveralls.io/github/exAspArk/batch-loader) [![Code Climate](https://img.shields.io/codeclimate/maintainability/exAspArk/batch-loader.svg)](https://codeclimate.com/github/exAspArk/batch-loader/maintainability) [![Downloads](https://img.shields.io/gem/dt/batch-loader.svg)](https://rubygems.org/gems/batch-loader) [![Latest Version](https://img.shields.io/gem/v/batch-loader.svg)](https://rubygems.org/gems/batch-loader) @@ -254,11 +253,11 @@ name "Post" field :user, UserType, null: false def user - post.user # N+1 queries + object.user # N+1 queries end end end module Types @@ -293,11 +292,11 @@ name "Post" field :user, UserType, null: false def user - BatchLoader::GraphQL.for(post.user_id).batch do |user_ids, loader| + 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 end end @@ -310,10 +309,42 @@ query Types::QueryType use BatchLoader::GraphQL 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 For batches where there is no item in response to a call, we normally return `nil`. However, you can use `:default_value` to return something else instead: