Skip to content

Commit 78f5e5f

Browse files
authored
Merge pull request #4870 from rmosolgo/pass-context-when-loading-arg-values
Pass context when fetching argument for loads
2 parents 718cd23 + a49ada5 commit 78f5e5f

File tree

2 files changed

+31
-19
lines changed

2 files changed

+31
-19
lines changed

lib/graphql/schema/member/has_arguments.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def argument(*args, **kwargs, &block)
5050
if loads && arg_defn.type.list?
5151
class_eval <<-RUBY, __FILE__, __LINE__ + 1
5252
def #{method_owner}load_#{arg_defn.keyword}(values, context = nil)
53-
argument = get_argument("#{arg_defn.graphql_name}")
53+
argument = get_argument("#{arg_defn.graphql_name}", context || self.context)
5454
(context || self.context).query.after_lazy(values) do |values2|
5555
GraphQL::Execution::Lazy.all(values2.map { |value| load_application_object(argument, value, context || self.context) })
5656
end
@@ -59,7 +59,7 @@ def #{method_owner}load_#{arg_defn.keyword}(values, context = nil)
5959
elsif loads
6060
class_eval <<-RUBY, __FILE__, __LINE__ + 1
6161
def #{method_owner}load_#{arg_defn.keyword}(value, context = nil)
62-
argument = get_argument("#{arg_defn.graphql_name}")
62+
argument = get_argument("#{arg_defn.graphql_name}", context || self.context)
6363
load_application_object(argument, value, context || self.context)
6464
end
6565
RUBY

spec/graphql/schema/dynamic_members_spec.rb

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,11 @@ def resolve(left:, right:)
268268
end
269269
end
270270

271+
class ThingIdInput < BaseInputObject
272+
argument :id, ID, future_schema: true, loads: Thing, as: :thing
273+
argument :id, Int, future_schema: false, loads: Thing, as: :thing
274+
end
275+
271276
class Query < BaseObject
272277
field :node, Node do
273278
argument :id, ID
@@ -285,12 +290,11 @@ def f1
285290
end
286291

287292
field :thing, Thing do
288-
argument :id, ID, future_schema: true
289-
argument :id, Int, future_schema: false
293+
argument :input, ThingIdInput
290294
end
291295

292-
def thing(id:)
293-
{ id: id, database_id: id, uuid: "thing-#{id}", legacy_price: "⚛︎#{id}00", price: { amount: id.to_i * 100, currency: "⚛︎" }}
296+
def thing(input:)
297+
input[:thing]
294298
end
295299

296300
field :legacy_thing, LegacyThing, null: false do
@@ -361,6 +365,14 @@ class Mutation < BaseObject
361365
query(Query)
362366
mutation(Mutation)
363367
orphan_types(Place, LegacyPlace, Locale, Region, Country)
368+
369+
def self.object_from_id(id, ctx)
370+
{ id: id, database_id: id, uuid: "thing-#{id}", legacy_price: "⚛︎#{id}00", price: { amount: id.to_i * 100, currency: "⚛︎" }}
371+
end
372+
373+
def self.resolve_type(type, obj, ctx)
374+
Thing
375+
end
364376
end
365377

366378
def check_for_multiple_visible_calls(context)
@@ -466,7 +478,7 @@ def legacy_schema_sdl
466478
favoriteLanguage(lang: Language): Language!
467479
legacyThing(id: ID!): LegacyThing!
468480
node(id: ID!): Node
469-
thing(id: Int!): Thing
481+
thing(input: ThingIdInput!): Thing
470482
yell(scream: Scream!): String!
471483
}
472484
GRAPHQL
@@ -479,7 +491,7 @@ def legacy_schema_sdl
479491
favoriteLanguage(lang: Language): Language!
480492
legacyThing(id: ID!): LegacyThing!
481493
node(id: ID!): Node
482-
thing(id: ID!): Thing
494+
thing(input: ThingIdInput!): Thing
483495
yell(scream: Scream!): String!
484496
}
485497
GRAPHQL
@@ -501,7 +513,7 @@ def legacy_schema_sdl
501513
}
502514
GRAPHQL
503515

504-
query_str = "{ thing(id: 15) { databaseId id uuid } }"
516+
query_str = "{ thing(input: { id: 15 }) { databaseId id uuid } }"
505517
assert_equal ["Field 'databaseId' doesn't exist on type 'Thing'", "Field 'uuid' doesn't exist on type 'Thing'"], exec_query(query_str)["errors"].map { |e| e["message"] }
506518
res = exec_future_query(query_str)
507519
assert_equal({ "thing" => { "databaseId" => 15, "id" => 15, "uuid" => "thing-15"} }, res["data"])
@@ -520,18 +532,18 @@ def legacy_schema_sdl
520532
end
521533

522534
it "supports different versions of field arguments" do
523-
res = exec_future_query("{ thing(id: \"15\") { id } }")
535+
res = exec_future_query("{ thing(input: { id: \"15\" }) { id } }")
524536
assert_equal 15, res["data"]["thing"]["id"]
525537
# On legacy, `"15"` is parsed as an int, which makes it null:
526-
res = exec_query("{ thing(id: \"15\") { id } }")
527-
assert_equal ["Argument 'id' on Field 'thing' has an invalid value (\"15\"). Expected type 'Int!'."], res["errors"].map { |e| e["message"] }
538+
res = exec_query("{ thing(input: { id: \"15\" }) { id } }")
539+
assert_equal ["Argument 'id' on InputObject 'ThingIdInput' has an invalid value (\"15\"). Expected type 'Int!'."], res["errors"].map { |e| e["message"] }
528540

529-
introspection_query = "{ __type(name: \"Query\") { fields { name args { name type { name ofType { name } } } } } }"
541+
introspection_query = "{ __type(name: \"ThingIdInput\") { inputFields { name type { name ofType { name } } } } }"
530542
introspection_res = exec_query(introspection_query)
531-
assert_equal "Int", introspection_res["data"]["__type"]["fields"].find { |f| f["name"] == "thing" }["args"].first["type"]["ofType"]["name"]
543+
assert_equal "Int", introspection_res["data"]["__type"]["inputFields"].find { |f| f["name"] == "id" }["type"]["ofType"]["name"]
532544

533545
introspection_res = exec_future_query(introspection_query)
534-
assert_equal "ID", introspection_res["data"]["__type"]["fields"].find { |f| f["name"] == "thing" }["args"].first["type"]["ofType"]["name"]
546+
assert_equal "ID", introspection_res["data"]["__type"]["inputFields"].find { |f| f["name"] == "id" }["type"]["ofType"]["name"]
535547
end
536548

537549
it "hides fields from hidden interfaces" do
@@ -654,22 +666,22 @@ def legacy_schema_sdl
654666
expected_message = "Found two visible definitions for `Money`: MultifieldSchema::Money, MultifieldSchema::MoneyScalar"
655667
assert_equal expected_message, err.message
656668

657-
assert_equal "⚛︎100",exec_query("{ thing(id: 1) { price } }")["data"]["thing"]["price"]
669+
assert_equal "⚛︎100",exec_query("{ thing( input: { id: 1 }) { price } }")["data"]["thing"]["price"]
658670
res = exec_query("{ __type(name: \"Money\") { kind name } }")
659671
assert_equal "SCALAR", res["data"]["__type"]["kind"]
660672
assert_equal "Money", res["data"]["__type"]["name"]
661-
assert_equal({ "amount" => 200, "currency" => "⚛︎" }, exec_future_query("{ thing(id: 2) { price { amount currency } } }")["data"]["thing"]["price"])
673+
assert_equal({ "amount" => 200, "currency" => "⚛︎" }, exec_future_query("{ thing(input: { id: 2}) { price { amount currency } } }")["data"]["thing"]["price"])
662674
res = exec_future_query("{ __type(name: \"Money\") { name kind } }")
663675
assert_equal "OBJECT", res["data"]["__type"]["kind"]
664676
assert_equal "Money", res["data"]["__type"]["name"]
665677
end
666678

667679
it "works with subclasses" do
668-
res = exec_query("{ legacyThing(id: 1) { price } thing(id: 3) { price } }")
680+
res = exec_query("{ legacyThing(id: 1) { price } thing(input: { id: 3 }) { price } }")
669681
assert_equal "⚛︎100", res["data"]["legacyThing"]["price"]
670682
assert_equal "⚛︎300", res["data"]["thing"]["price"]
671683

672-
future_res = exec_future_query("{ legacyThing(id: 1) { price } thing(id: 3) { price { amount } } }")
684+
future_res = exec_future_query("{ legacyThing(id: 1) { price } thing(input: { id: 3 }) { price { amount } } }")
673685
assert_equal "⚛︎100", future_res["data"]["legacyThing"]["price"]
674686
assert_equal 300, future_res["data"]["thing"]["price"]["amount"]
675687
end

0 commit comments

Comments
 (0)