I have a two-fold problem with graphql query batching. We're using https://github.com/rmosolgo/graphql-ruby v1.12 and https://github.com/Shopify/graphql-batch v0.5.1.
First, I have an existing type resolver defined like this:
field :languages, Types::LanguageType.connection_type, null: true
def languages
Language.all
end
So it's basically like an /index endpoint in REST. I want to change it to accept an optional argument that filters it down, e.g.
argument :active_only, Boolean, required: false, default_value: false
def languages(active_only: false)
scope = Languages.all
scope = scope.active if active_only
scope
end
Simple enough. But now I'm also trying to add collection_count, which is an association on the object that I want to eager-load if and only if that association's field is part the original request query.
class Language < ApplicationRecord
has_one :metadata
def collection_count
metadata&.collection_count || 0
end
end
module Types
class LanguageType < GraphQL::Schema::Object
field :english_name, String, null: true
field :collection_count, Integer, null: false
end
end
The graphql-batch docs don't indicate how I'm supposed to batch a scope/activerecord relation WITH an association, and I've tried various iterations that don't work. For instance:
RecordLoader.for(Language).load_many(scope.map(&:id)).then do |langs|
AssociationLoader.for(Language, :metadata).load_many(langs)
end
RuntimeError - Failed to implement Language.englishName, tried:
- `Types::LanguageType#english_name`, which did not exist
- `Metadata#english_name`, which did not exist
- Looking up hash key `:english_name` or `"english_name"` on `#<Metadata:0x000000010f4418e8>`, but it wasn't a Hash
The above example also ends up querying Languages TWICE, once when we pass in the scope's IDs, and again on the call to RecordLoader.
We've defined an AssociationLoader that looks like it's pretty much this: https://github.com/Shopify/graphql-batch/blob/master/examples/association_loader.rb
Any help is appreciated!