Skip to content

exec-next: Add method: to dataload shorthands - #5706

Merged
rmosolgo merged 1 commit into
rmosolgo:masterfrom
OuYangJinTing:exec-next-dataload-method-shorthand
Aug 20, 2026
Merged

exec-next: Add method: to dataload shorthands#5706
rmosolgo merged 1 commit into
rmosolgo:masterfrom
OuYangJinTing:exec-next-dataload-method-shorthand

Conversation

@OuYangJinTing

@OuYangJinTing OuYangJinTing commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Motivation

A very common pattern in our schema is resolving a scalar by first batch-loading an association, then calling a method on the loaded associated object.

Without this PR, every such field requires a custom def self.<field> batch resolver. For example, in our UserType we end up with a lot of boilerplate like this:

# app/graphql/types/user_type.rb
field :age, String, null: true, resolve_batch: true

def self.age(objects, context)
  dataload_all_associations(context, objects, :verified_info).map { it&.age }
end

field :country, String, null: true, resolve_batch: true

def self.country(objects, context)
  dataload_all_associations(context, objects, :latest_device).map { it&.country }
end

def self.dataload_all_associations(context, records, association_name, scope: nil)
  source = if scope
             context.dataloader.with(GraphQL::Dataloader::ActiveRecordAssociationSource, association_name, scope)
           else
             context.dataloader.with(GraphQL::Dataloader::ActiveRecordAssociationSource, association_name)
           end
  source.load_all(records)
end

This becomes repetitive quickly and makes the type file mostly boilerplate.

With the method: option on dataload: shorthands, the same fields can be written declaratively:

field :age, String, null: true,
      dataload: { association: :verified_info, method: :age }

field :country, String, null: true,
      dataload: { association: :latest_device, method: :country }

It keeps the dataloader batching, removes the need for one resolver per field, and makes the schema definition a lot more readable. Because method: works for with:, association:, and model: shorthands, it covers most of our real-world cases.

Summary

  • Adds a method: option to hash-style dataload: field configs under Execution::Next. When present, the loaded value's public method is called before returning it, e.g. dataload: { association: :author, method: :name } is equivalent to dataload_association(:author)&.name.
  • Works with all three hash-style shorthands (with:, association:, model:).
  • Updated guides/execution/next.md with examples for each shorthand.

Tests

Added specs covering method: for the source shorthand, the Rails association shorthand, and the Rails model shorthand.

@rmosolgo rmosolgo added this to the 2.6.10 milestone Aug 20, 2026
@rmosolgo

Copy link
Copy Markdown
Owner

Thanks for this improvement! I agree this is a nice convenience.

@rmosolgo
rmosolgo merged commit 54bb571 into rmosolgo:master Aug 20, 2026
14 of 15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants