ksylvest/graphql-sources

View on GitHub
lib/graphql/sources/active_storage_has_one_attached.rb

Summary

Maintainability
A
0 mins
Test Coverage
A
100%
# frozen_string_literal: true

module GraphQL
  module Sources
    # A class for loading `has_one_attached` style associations.
    #
    #   class User
    #     has_one_attached :photo
    #   end
    #
    #   class UserType < GraphQL::Schema::Object
    #     field :avatar, AttachedType, null: false
    #
    #     def avatar
    #       dataloader
    #         .with(GraphQL::Sources::ActiveStorageHasOneAttached, :avatar)
    #         .load(object)
    #     end
    #   end
    #
    # The resulting SQL query is:
    #
    #     SELECT "active_storage_attachments".*
    #     FROM "active_storage_attachments"
    #     WHERE "active_storage_attachments"."name" = 'avatar'
    #       AND "active_storage_attachments"."record_type" = 'User'
    #       AND "active_storage_attachments"."record_id" IN (...)
    class ActiveStorageHasOneAttached < ActiveStorageBase
      # @param records [Array<ActiveRecord::Base>] an array of records
      # @return [Array] indexed attachments mirroring the keys
      def fetch(records)
        attachments = attachments(records: records).load_async
        dataloader.yield

        map = attachments.index_by { |attachment| [attachment.record_type, attachment.record_id] }
        records.map { |record| map[[record.class.name, record.id]] }
      end
    end
  end
end