Skip to content

Commit 27ac567

Browse files
committed
Support extensions with resolve procs
1 parent 8eaef47 commit 27ac567

File tree

2 files changed

+43
-18
lines changed

2 files changed

+43
-18
lines changed

lib/graphql/schema/field.rb

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -277,15 +277,6 @@ def extensions(new_extensions = nil)
277277
# Read the value
278278
@extensions
279279
else
280-
if @resolve || @function
281-
raise ArgumentError, <<-MSG
282-
Extensions are not supported with resolve procs or functions,
283-
but #{owner.name}.#{name} has: #{@resolve || @function}
284-
So, it can't have extensions: #{extensions}.
285-
Use a method or a Schema::Resolver instead.
286-
MSG
287-
end
288-
289280
# Normalize to a Hash of {name => options}
290281
extensions_with_options = if new_extensions.last.is_a?(Hash)
291282
new_extensions.pop
@@ -454,12 +445,16 @@ def resolve_field(obj, args, ctx)
454445
# @see https://github.com/rmosolgo/graphql-ruby/issues/1990 before removing
455446
inner_obj = after_obj && after_obj.object
456447
if authorized?(inner_obj, query_ctx)
448+
ruby_args = to_ruby_args(after_obj, args, ctx)
457449
# Then if it passed, resolve the field
458450
if @resolve_proc
459451
# Might be nil, still want to call the func in that case
460-
@resolve_proc.call(inner_obj, args, ctx)
452+
with_extensions(inner_obj, ruby_args, query_ctx) do |extended_obj, extended_args|
453+
# Pass the GraphQL args here for compatibility:
454+
@resolve_proc.call(extended_obj, args, ctx)
455+
end
461456
else
462-
public_send_field(after_obj, args, ctx)
457+
public_send_field(after_obj, ruby_args, ctx)
463458
end
464459
else
465460
err = GraphQL::UnauthorizedFieldError.new(object: inner_obj, type: obj.class, context: ctx, field: self)
@@ -568,7 +563,13 @@ def fetch_extra(extra_name, ctx)
568563

569564
NO_ARGS = {}.freeze
570565

571-
def public_send_field(obj, graphql_args, field_ctx)
566+
# Convert a GraphQL arguments instance into a Ruby-style hash.
567+
#
568+
# @param obj [GraphQL::Schema::Object] The object where this field is being resolved
569+
# @param graphql_args [GraphQL::Query::Arguments]
570+
# @param field_ctx [GraphQL::Query::Context::FieldResolutionContext]
571+
# @return [Hash<Symbol => Any>]
572+
def to_ruby_args(obj, graphql_args, field_ctx)
572573
if graphql_args.any? || @extras.any?
573574
# Splat the GraphQL::Arguments to Ruby keyword arguments
574575
ruby_kwargs = graphql_args.to_kwargs
@@ -583,10 +584,14 @@ def public_send_field(obj, graphql_args, field_ctx)
583584
@extras.each do |extra_arg|
584585
ruby_kwargs[extra_arg] = fetch_extra(extra_arg, field_ctx)
585586
end
587+
588+
ruby_kwargs
586589
else
587-
ruby_kwargs = NO_ARGS
590+
NO_ARGS
588591
end
592+
end
589593

594+
def public_send_field(obj, ruby_kwargs, field_ctx)
590595
query_ctx = field_ctx.query.context
591596
with_extensions(obj, ruby_kwargs, query_ctx) do |extended_obj, extended_args|
592597
if @resolver_class

spec/graphql/schema/member/scoped_spec.rb

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,17 @@ class Query < BaseObject
5757
resolver_method: :items
5858
field :french_items, [FrenchItem], null: false,
5959
resolver_method: :items
60-
field :items_connection, Item.connection_type, null: false,
61-
resolver_method: :items
60+
if TESTING_INTERPRETER
61+
field :items_connection, Item.connection_type, null: false,
62+
resolver_method: :items
63+
else
64+
field :items_connection, Item.connection_type, null: false, resolve: ->(obj, args, ctx) {
65+
[
66+
OpenStruct.new(name: "Trombone"),
67+
OpenStruct.new(name: "Paperclip"),
68+
]
69+
}
70+
end
6271

6372
def items
6473
[
@@ -67,9 +76,20 @@ def items
6776
]
6877
end
6978

70-
field :things, [Thing], null: false
71-
def things
72-
items + [OpenStruct.new(name: "Turbine")]
79+
if TESTING_INTERPRETER
80+
field :things, [Thing], null: false
81+
def things
82+
items + [OpenStruct.new(name: "Turbine")]
83+
end
84+
else
85+
# Make sure it works with resolve procs, too
86+
field :things, [Thing], null: false, resolve: ->(obj, args, ctx) {
87+
[
88+
OpenStruct.new(name: "Trombone"),
89+
OpenStruct.new(name: "Paperclip"),
90+
OpenStruct.new(name: "Turbine"),
91+
]
92+
}
7393
end
7494
end
7595

0 commit comments

Comments
 (0)