Skip to content

Personal collection of loaders for use with graphql-batch

License

Notifications You must be signed in to change notification settings

antoinematyja/graphql-batch-loaders

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 

Repository files navigation

Loaders for graphql-batch

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.

Invocation

CountLoader.for(model, field).load(value)

Non-batched equivalent

model.where(field => value).count

Example

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.

Invocation

AssociationCountLoader.for(model, association).load(record)

Non-batched equivalent

model.association.count

Example

has_many

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

has_and_belongs_to_many

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

has_many :through

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.

Invocation

AssociationFindByLoader.for(record, association, field)
      .load(value)(record)

Non-batched equivalent

record.association.find_by(field: value)

Example

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

About

Personal collection of loaders for use with graphql-batch

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Ruby 100.0%