Skip to content

Instantly share code, notes, and snippets.

@hieuns
Created October 4, 2019 04:31
Show Gist options
  • Save hieuns/11c2d8217131cf1776e5785700a3cfec to your computer and use it in GitHub Desktop.
Save hieuns/11c2d8217131cf1776e5785700a3cfec to your computer and use it in GitHub Desktop.
Use graphql-batch with graphql-ruby to resolve n + 1 issue
module Types
class ItemType < GraphQL::Schema::Object
field :id, ID, null: false
field :title, String, null: false
field :description, String, null: true
field :image_url, String, null: true
# (graphql-ruby 1.9.12)
# instead of using `resolve` inside block of `field` like this:
#
# field :user, Types::UserType, null: false do
# resolve ->(item, args, ctx) do
# Loaders::PrimaryKeyLoader.for(User).load item.user_id
# end
# end
#
# we should use a pair of key-value like below:
field :user, Types::UserType, null: false, resolve: ->(item, args, ctx) do
Loaders::PrimaryKeyLoader.for(User).load item.user_id
end
end
end
module Loaders
class PrimaryKeyLoader < GraphQL::Batch::Loader
def initialize model
@model = model
end
def perform ids
@model.where(id: ids).each{|record| fulfill record.id, record}
ids.each{|id| fulfill(id, nil) unless fulfilled?(id)}
end
end
end
module Types
class UserType < GraphQL::Schema::Object
field :id, ID, null: false
field :email, String, null: false
field :full_name, String, null: false
def full_name
[object.first_name, object.last_name].compact.join " "
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment