Ruby Graphql batch loading for ActiveRecord::Relation and associations

312 Views Asked by At

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!

0

There are 0 best solutions below