Dataloader & N+1
Overview
Section titled “Overview”Quail enables GraphQL::Dataloader on your schema automatically via SchemaBuilder.install_defaults. This means batched, lazy-loaded resolution is available out of the box — you don’t need to add use GraphQL::Dataloader yourself.
What This Gives You
Section titled “What This Gives You”When graphql-ruby resolves nested associations (e.g., a list of subscriptions each loading their associated user and profile), the dataloader batches those loads into fewer queries instead of issuing one query per record. This prevents the classic N+1 problem that plagues deeply nested GraphQL queries.
Eager Loading in Custom Queries
Section titled “Eager Loading in Custom Queries”For custom queries that return relations with known association depth, use ActiveRecord’s includes to preload associations in a single pass:
class MySubscribers < Quail::Query type :subscription, connection: true, null: false
def resolve Subscription.where(user: context[:current_user]) .includes(subscriber: { profile: { avatar_attachment: :blob } }) .order(created_at: :desc) endendThe includes call tells ActiveRecord to batch-load the subscriber, profile, and Active Storage avatar_attachment associations upfront. Combined with the dataloader, this keeps query count constant regardless of page size.
Guidelines
Section titled “Guidelines”- Use
includesin customQuail::Queryresolvers when you know which associations the client will request. This is the most effective way to prevent N+1s in practice. - For auto-generated resource queries, the dataloader handles batching at the GraphQL resolver level — no extra configuration needed.
- If you override
SchemaBuilder.install_defaultsor set your owndataloader_class, the automatic setup is skipped and you’re responsible for configuring the dataloader yourself.