I didn't found it in the repo yet. I tried to mix old Relay mutation types and others, but it can't work.
Could you share an example error from Relay mutations, perhaps with a snippet of source code?
As for connections, sorry it's not well documented, but connections are applied by convention:
Connection, the field is treated like a connection (this replaces the old connection ... method connection: kwarg Determine if a field is a connection:
Apply the determined value:
Let's keep this open until the docs are improved.
The following is a snippet:
Mutations::Shared::Create = GraphQL::Relay::Mutation.define do
name "CreateShared"
return_field :result, Types::SharedType
return_field :errors, Types::ErrorsType
input_field :title, !types.String
input_field :description, types.String
input_field :cover, !Types::FileType # <------ ERROR LINE
resolve ->(obj, args, ctx) {
# ...
}
end
Error:
GraphQL::Schema::InvalidTypeError (Argument input on Mutation.createShared is invalid: argument "cover" type must be a valid input type (Scalar or InputObject), not NilClass ()):
Types::FileType is class-based type. When I comment this line, it works fine. So I think maybe just let input_field supports null: false argument.
I'll test connection later.
Yay, connection works fine. 鉁岋笍
Another error (full log at the end):
LoadError (Unable to autoload constant Types::UserType, expected /Users/lijie/backend/app/graphql/types/user_type.rb to define it):
Content of app/graphql/types/user_type.rb:
class Types::UserType < GraphQL::Schema::Object
graphql_name "User"
field :id, ID, null: false
field :email, String, null: false
field :authentication_token, String, null: false
field :inactive, String, null: true,
resolve: -> (user, args, ctx) {
user.confirmed? ? nil : user.inactive_message
}
field :user_info, Types::UserInfoType, null: false
end
UPDATED:
This error caused after I change the ERROR LINE above to:
input_field :cover, Types::FileType, required: true
The content of types/file_type.rb:
class Types::FileType < GraphQL::Schema::Scalar
graphql_name "File"
end
After I removed required: true, it works.
BTW: This test is refreshing GraphiQL page.
END UPDATED
Full log:
lijie$ bundle exec rails s -p 3876
/Users/lijie/.rvm/gems/ruby-2.4.1/gems/word_salad-2.0.0/lib/word_salad/core_ext.rb:1: warning: constant ::Fixnum is deprecated
DEPRECATION WARNING: The factory_girl gem is deprecated. Please upgrade to factory_bot. See https://github.com/thoughtbot/factory_bot/blob/v4.9.0/UPGRADE_FROM_FACTORY_GIRL.md for further instructions. (called from <top (required)> at /Users/lijie/backend/config/application.rb:7)
=> Booting Puma
=> Rails 5.1.4 application starting in development
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.11.0 (ruby 2.4.1-p111), codename: Love Song
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://localhost:3876
Use Ctrl-C to stop
Started GET "/graphiql" for ::1 at 2017-12-01 10:38:31 +0800
(0.5ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
Processing by GraphiQL::Rails::EditorsController#show as HTML
Parameters: {"graphql_path"=>"/graphql"}
Rendering /Users/lijie/.rvm/gems/ruby-2.4.1/gems/graphiql-rails-1.4.8/app/views/graphiql/rails/editors/show.html.erb
Rendered /Users/lijie/.rvm/gems/ruby-2.4.1/gems/graphiql-rails-1.4.8/app/views/graphiql/rails/editors/show.html.erb (602.3ms)
Completed 200 OK in 652ms (Views: 635.4ms | ActiveRecord: 0.0ms)
Started POST "/graphql" for ::1 at 2017-12-01 10:38:32 +0800
Processing by GraphqlController#execute as */*
Parameters: {"query"=>"\n query IntrospectionQuery {\n __schema {\n queryType { name }\n mutationType { name }\n subscriptionType { name }\n types {\n ...FullType\n }\n directives {\n name\n description\n locations\n args {\n ...InputValue\n }\n }\n }\n }\n\n fragment FullType on __Type {\n kind\n name\n description\n fields(includeDeprecated: true) {\n name\n description\n args {\n ...InputValue\n }\n type {\n ...TypeRef\n }\n isDeprecated\n deprecationReason\n }\n inputFields {\n ...InputValue\n }\n interfaces {\n ...TypeRef\n }\n enumValues(includeDeprecated: true) {\n name\n description\n isDeprecated\n deprecationReason\n }\n possibleTypes {\n ...TypeRef\n }\n }\n\n fragment InputValue on __InputValue {\n name\n description\n type { ...TypeRef }\n defaultValue\n }\n\n fragment TypeRef on __Type {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n }\n }\n }\n }\n }\n }\n }\n }\n", "graphql"=>{"query"=>"\n query IntrospectionQuery {\n __schema {\n queryType { name }\n mutationType { name }\n subscriptionType { name }\n types {\n ...FullType\n }\n directives {\n name\n description\n locations\n args {\n ...InputValue\n }\n }\n }\n }\n\n fragment FullType on __Type {\n kind\n name\n description\n fields(includeDeprecated: true) {\n name\n description\n args {\n ...InputValue\n }\n type {\n ...TypeRef\n }\n isDeprecated\n deprecationReason\n }\n inputFields {\n ...InputValue\n }\n interfaces {\n ...TypeRef\n }\n enumValues(includeDeprecated: true) {\n name\n description\n isDeprecated\n deprecationReason\n }\n possibleTypes {\n ...TypeRef\n }\n }\n\n fragment InputValue on __InputValue {\n name\n description\n type { ...TypeRef }\n defaultValue\n }\n\n fragment TypeRef on __Type {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n }\n }\n }\n }\n }\n }\n }\n }\n"}}
User Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 1], ["LIMIT", 1]]
Completed 500 Internal Server Error in 153ms (ActiveRecord: 2.1ms)
LoadError (Unable to autoload constant Types::UserType, expected /Users/lijie/backend/app/graphql/types/user_type.rb to define it):
app/controllers/graphql_controller.rb:20:in `execute'
Started POST "/graphql" for ::1 at 2017-12-01 10:38:33 +0800
Processing by GraphqlController#execute as */*
Parameters: {"query"=>"\n query IntrospectionQuery {\n __schema {\n queryType { name }\n mutationType { name }\n types {\n ...FullType\n }\n directives {\n name\n description\n locations\n args {\n ...InputValue\n }\n }\n }\n }\n\n fragment FullType on __Type {\n kind\n name\n description\n fields(includeDeprecated: true) {\n name\n description\n args {\n ...InputValue\n }\n type {\n ...TypeRef\n }\n isDeprecated\n deprecationReason\n }\n inputFields {\n ...InputValue\n }\n interfaces {\n ...TypeRef\n }\n enumValues(includeDeprecated: true) {\n name\n description\n isDeprecated\n deprecationReason\n }\n possibleTypes {\n ...TypeRef\n }\n }\n\n fragment InputValue on __InputValue {\n name\n description\n type { ...TypeRef }\n defaultValue\n }\n\n fragment TypeRef on __Type {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n }\n }\n }\n }\n }\n }\n }\n }\n", "graphql"=>{"query"=>"\n query IntrospectionQuery {\n __schema {\n queryType { name }\n mutationType { name }\n types {\n ...FullType\n }\n directives {\n name\n description\n locations\n args {\n ...InputValue\n }\n }\n }\n }\n\n fragment FullType on __Type {\n kind\n name\n description\n fields(includeDeprecated: true) {\n name\n description\n args {\n ...InputValue\n }\n type {\n ...TypeRef\n }\n isDeprecated\n deprecationReason\n }\n inputFields {\n ...InputValue\n }\n interfaces {\n ...TypeRef\n }\n enumValues(includeDeprecated: true) {\n name\n description\n isDeprecated\n deprecationReason\n }\n possibleTypes {\n ...TypeRef\n }\n }\n\n fragment InputValue on __InputValue {\n name\n description\n type { ...TypeRef }\n defaultValue\n }\n\n fragment TypeRef on __Type {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n }\n }\n }\n }\n }\n }\n }\n }\n"}}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 1], ["LIMIT", 1]]
Completed 500 Internal Server Error in 8ms (ActiveRecord: 0.3ms)
LoadError (Unable to autoload constant Types::UserType, expected /Users/lijie/backend/app/graphql/types/user_type.rb to define it):
app/controllers/graphql_controller.rb:20:in `execute'
A problem not relatived to Relay.
For those tests, I must restart again and again when some errors cause. Your patch https://github.com/rmosolgo/graphql-ruby/issues/651#issuecomment-292718619 works not good for new API. It can't reload the module after fixed some error, but if remove it, the rails server will hang.
Oh, I see. ! doesn't create non-null types anymore, but I didn't document it 馃槚
I removed the ! API, you can backport it with:
A lexically-scoped refinement:
A globably-scoped monkey-patch:
Thanks. Using GraphQL::DeprecatedDSL now.
But I think it deprecated, what is the new way?
Another error:
using GraphQL::DeprecatedDSL
Mutations::Gist::Update = GraphQL::Relay::Mutation.define do
name "UpdateGist"
return_field :result, Types::GistType
return_field :errors, Types::ErrorsType
input_field :id, !types.ID
input_field :title, types.String
input_field :description, types.String
input_field :public, types.Boolean
input_field :text_files, types[!Types::TextFileInputType] #<-- CAUSE ERROR
resolve ->(_, args, ctx) {
# ...
}
end
class Types::TextFileInputType < GraphQL::Schema::InputObject
graphql_name "TextFileInput"
argument :path, String, required: false
argument :data, String, required: false
end
When I comment out that line, no errors again.
And the error is:
LoadError (Unable to autoload constant Types::UserType, expected /Users/lijie/backend/app/graphql/types/user_type.rb to define it):
app/controllers/graphql_controller.rb:20:in `execute'
But Types::UserType hasn't errors.
Woah! That's a weird one. Is there any line in the backtrace that references UserType?
I added docs for GraphQL::DeprecatedDSL in bae8e422
Another alternative is #to_non_null_type, for example:
input_field :cover, !Types::FileType
# could be
input_field :cover, Types::FileType.to_non_null_type
Also, added an example connection field in f76062ee33a1ecfff3f62841802369120dab9334 !
Thanks. I met an error when I used Types::FileType.to_non_null_type.to_list_type to instead of types[!Types::FileType], and it worked using Types::FileType.to_list_type, but its GraphQL type is [FileType], I need it [FileType!]. How to distinguish Array of Nullable FileType and Array of Non-nullable FileType? I think this case is common.
UPDATE:
I need Oh, I think we can use [FileType!]! type too, it can deny someone pass null to an array type.required: or null: for this case.
The methods are additive, so maybe changing the order will help, for example:
Types::FileType.to_non_null_type # => FileType!
Types::FileType.to_non_null_type.to_list_type # [FileType!]
Types::FileType.to_list_type # => [FileType]
Types::FileType.to_list_type.to_non_null_type # => [FileType]!
# All together now :P
Types::FileType.to_non_null_type.to_list_type.to_non_null_type # => [FileType!]!
I used your example but can't works still.
Some new errors:
Both of them cause after server restarted and refresh GraphiQL. I think I should create a repo to reproduce.
_IGNORE ABOVE: (Those errors causes when I used to_non_null_type in class-based definition.)_
Currently the result of some cases (in Relay mutation):
The following works fine:
return_field :files, Types::SourceFileType.to_non_null_type
return_field :files, Types::SourceFileType.to_list_type
input_field :text_files, Types::TextFileInputType.to_non_null_type
input_field :text_files, Types::TextFileInputType.to_list_type
The following causes errors:
LoadError (Unable to autoload constant Types::UserType, expected /Users/lijie/source/applean/applean-api/app/graphql/types/user_type.rb to define it):
_(Ignore UserType because if I comment out some fields about UserType, the error message change to another type)_
return_field :files, Types::SourceFileType.to_non_null_type.to_list_type
return_field :files, Types::SourceFileType.to_non_null_type.to_list_type.to_non_null_type
return_field :files, Types::SourceFileType.to_list_type.to_non_null_type
input_field :text_files, Types::TextFileInputType.to_non_null_type.to_list_type
input_field :text_files, Types::TextFileInputType.to_non_null_type.to_list_type.to_non_null_type
input_field :text_files, Types::TextFileInputType.to_list_type.to_non_null_type
Create a repo https://github.com/cpunion/reproduce-graphql-ruby-mutation-error, currently it always causes the following error and I can't reproduce other errors.
ArgumentError (A copy of Types has been removed from the module tree but is still active!):
app/graphql/reproduce_graphql_ruby_mutation_error_schema.rb:2:in `<class:ReproduceGraphqlRubyMutationErrorSchema>'
app/graphql/reproduce_graphql_ruby_mutation_error_schema.rb:1:in `<top (required)>'
app/controllers/graphql_controller.rb:10:in `execute'
To test it, just open /graphiql and refresh page. Doesn't need call some query.
When I see the "expected QueryType to define it" LoadError, I've had some success opening a Rails console and typing the name of my schema. This gives me a much more specific and helpful error message, for example:
[1] pry(main)> ApiSchema
NameError: uninitialized constant Types::CompanyType
from /Users/zubin/code/rails/app/graphql/resolvers/find_company.rb:6:in `<class:FindCompany>'
That particular error happened because I renamed the class to Types::Company but forgot to update the resolver, but I've found lots of other problems this way too.
I'm going to close this because I don't see any action items left to address, please feel free to open another issue if there's still something to do here!
@rmosolgo unsure if I should reopen or not (the docs are still on the same ; but I'm having hard times understanding how the GraphQL::Relay::Mutation should be used in a class based context - using a class based approach, input_field and return_field are unavailable
May I suggest you to provide a minimal example here ?
GraphQL::Relay::Mutation has been replaced by GraphQL::Schema::RelayClassicMutation, which is a subclass of GraphQL::Schema::Resolver. see
https://graphql-ruby.org/api-doc/1.9.14/GraphQL/Schema/RelayClassicMutation
https://graphql-ruby.org/mutations/mutation_classes
https://graphql-ruby.org/fields/resolvers.html
I've tried to indicate that in the docs:

Feel free to use the "Edit" button the website if you'd like to suggest a specific change!
@rmosolgo oh i see, though that "classic" was about a previous version; my bad. thx a lot for your reply;