This is a personal collection of graphql-batch loaders that I have either authored or modified to my requirements, they are provided as-is and might help someone looking for a specific niche loader.
Loader | Purpose |
---|---|
CountLoader | Batches counts on a model by values of a specific field. |
AssociationCountLoader | Batches counts on a model through a defined association. |
AssociationFindByLoader | Finds single records through an association on a record by a specific value on the associated table. |
Batches counts on a model by values of a specific field.
Additional information can be found at this blog post.
CountLoader.for(model, field).load(value)
model.where(field => value).count
class User < ApplicationRecord
has_many :posts
end
class Post < ApplicationRecord
belongs_to :user
end
class Types::UserType < Types::BaseObject
field :post_count, Integer
def post_count
CountLoader.for(Post, :user_id).load(object.id)
end
end
Batches counts on a model through a defined association.
Additional information can be found at this blog post.
AssociationCountLoader.for(model, association).load(record)
model.association.count
class User < ApplicationRecord
has_many :posts
end
class Post < ApplicationRecord
belongs_to :user
end
class Types::UserType < Types::BaseObject
field :post_count, Integer
def post_count
AssociationCountLoader.for(User, :posts).load(object)
end
end
class User < ApplicationRecord
has_and_belongs_to_many :posts, inverse_of: :users
end
class Post < ApplicationRecord
has_and_belongs_to_many :users
end
class Types::UserType < Types::BaseObject
field :post_count, Integer
def post_count
AssociationCountLoader.for(User, :posts).load(object)
end
end
class User < ApplicationRecord
has_many :posts
has_many :comments, through: :posts, inverse_of: :user
end
class Post < ApplicationRecord
belongs_to :user
has_many :comments
end
class Comment < ApplicationRecord
belongs_to :post
has_one :user, through: :post
end
class Types::UserType < Types::BaseObject
field :comment_count, Integer
def comment_count
AssociationCountLoader.for(User, :comments).load(object)
end
end
Finds single records through an association on a record by a specific value on the associated table.
This is very useful for edge types on collections to batch load join models based off of the current user.
AssociationFindByLoader.for(record, association, field)
.load(value)(record)
record.association.find_by(field: value)
This is a more in-depth example and not all ActiveRecord associations or GraphQL types are fully fleshed out. The following demonstrates a concrete use-case.
class User < ApplicationRecord
has_many :group_memberships
has_many :groups, through: :group_memberships
end
class GroupMembership < ApplicationRecord
belongs_to :user
belongs_to :group
enum :role, [ :member, :admin ]
end
class Group < ApplicationRecord
end
class Types::GroupType < Types::BaseObject
edge_type_class Types::GroupMembershipEdge
end
class Types::GroupMembershipEdge < Types::BaseEdge
field :role, Types::GroupMembershipEdgeEnum, null: false
def role
AssociationFindByLoader
.for(current_user, :group_memberships, :group_id)
.load(node.id)
.then(&:role)
end
end