我没有使用继电器。
我已经阅读了一些教程。许多人用这种方式进行突变:
应用/ graphql / graphql_tutorial_schema.rb
GraphqlTutorialSchema = GraphQL::Schema.define do
query(Types::QueryType)
mutation(Types::MutationType)
end
应用/ graphql /解析器/ create_link.rb
class Resolvers::CreateLink < GraphQL::Function
argument :description, !types.String
argument :url, !types.String
type Types::LinkType
def call(_obj, args, _ctx)
Link.create!(
description: args[:description],
url: args[:url],
)
end
end
最后他们有:
应用/ graphql /类型/ mutation_type.rb
Types::MutationType = GraphQL::ObjectType.define do
name 'Mutation'
field :createLink, function: Resolvers::CreateLink.new
end
所以他们使用的是GraphQL::Function
。
这是要走的路吗?如果我不使用Relay,这只是唯一的方法吗?
如果我想要所有link
操作(CRUD)的唯一文件怎么办?
其他教程(http://tech.eshaiju.in/blog/2017/05/15/graphql-mutation-query-implementation-ruby-on-rails/)使用此:
应用/ graphql /突变/ comment_mutations.rb
module CommentMutations
Create = GraphQL::Relay::Mutation.define do
name "AddComment"
# Define input parameters
input_field :articleId, !types.ID
input_field :userId, !types.ID
input_field :comment, !types.String
# Define return parameters
return_field :article, ArticleType
return_field :errors, types.String
resolve ->(object, inputs, ctx) {
article = Article.find_by_id(inputs[:articleId])
return { errors: 'Article not found' } if article.nil?
comments = article.comments
new_comment = comments.build(user_id: inputs[:userId], comment: inputs[:comment])
if new_comment.save
{ article: article }
else
{ errors: new_comment.errors.to_a }
end
}
end
end
和 app / graphql / mutation / mutation_type.rb
MutationType = GraphQL::ObjectType.define do
name "Mutation"
# Add the mutation's derived field to the mutation type
field :addComment, field: CommentMutations::Create.field
end
所以我也可以添加:
MutationType = GraphQL::ObjectType.define do
name "Mutation"
field :addComment, field: CommentMutations::Create.field
field :updateComment, field: CommentMutations::Update.field
field :deleteComment, field: CommentMutations::Delete.field
end
但这只适用于Create = GraphQL::Relay::Mutation.define
:我没有使用Relay !
在您的文档中,我发现与此问题无关。
我必须始终使用GraphQL :: Functions?
或许我可以这样使用它:
MutationType = GraphQL::ObjectType.define do
name "Mutation"
field :addComment, field: CommentMutations::Create
field :updateComment, field: CommentMutations::Update
field :deleteComment, field: CommentMutations::Delete
end
并且有这个(代码就是一个例子):
module Mutations::commentMutations
Createcomment = GraphQL::ObjectType.define do
name "Createcomment"
input_field :author_id, !types.ID
input_field :post_id, !types.ID
return_field :comment, Types::commentType
return_field :errors, types.String
resolve ->(obj, inputs, ctx) {
comment = comment.new(
author_id: inputs[:author_id],
post_id: inputs[:post_id]
)
if comment.save
{ comment: comment }
else
{ errors: comment.errors.to_a }
end
}
end
Updatecomment = GraphQL::ObjectType.define do
name "Updatecomment"
input_field :author_id, !types.ID
input_field :post_id, !types.ID
return_field :comment, Types::commentType
return_field :errors, types.String
resolve ->(obj, inputs, ctx) {
comment = comment.new(
author_id: inputs[:author_id],
post_id: inputs[:post_id]
)
if comment.update
{ comment: comment }
else
{ errors: comment.errors.to_a }
end
}
end
end
这是另一种方式吗?
答案 0 :(得分:0)
看看我目前的样子:
blah_schema.rb
BlahSchema = GraphQL::Schema.define do
...
query(Types::QueryType)
mutation_type.rb
Types::MutationType = GraphQL::ObjectType.define do
name "Mutation"
field :comment, !Types::CommentType do
argument :resource_type, !types.String
argument :resource_id, !types.ID
argument :comment, !types.String
resolve ResolverErrorHandler.new ->(obj, args, ctx) do
ctx[:current_user].comments.
create!(resource_id: args[:resource_id],
resource_type: args[:resource_type],
comment: args[:comment])
end
end
field :destroy_comment, !Types::CommentType do
argument :id, !types.ID
resolve ResolverErrorHandler.new ->(obj, args, ctx) do
comment = ctx[:current_user].comments.where(id: args[:id]).first
if !comment
raise ActiveRecord::RecordNotFound.new(
"couldn't find comment for id #{args[:id]} belonging to #{current_user.id}")
end
comment.destroy!
comment
end
end
end
resolver_error_handler.rb
class ResolverErrorHandler
def initialize(resolver)
@r = resolver
end
def call(obj, args, ctx)
@r.call(obj, args, ctx)
rescue ActiveRecord::RecordNotFound => e
GraphQL::ExecutionError.new("Missing Record: #{e.message}")
rescue AuthorizationError => e
GraphQL::ExecutionError.new("sign in required")
rescue ActiveRecord::RecordInvalid => e
# return a GraphQL error with validation details
messages = e.record.errors.full_messages.join("\n")
GraphQL::ExecutionError.new("Validation failed: #{messages}")
rescue StandardError => e
# handle all other errors
Rails.logger.error "graphql exception caught: #{e} \n#{e.backtrace.join("\n")}"
Raven.capture_exception(e)
GraphQL::ExecutionError.new("Unexpected error!")
end
end
所以是的,它是不同的 - 我不确定它是否更好,这正是我提出的。我的mutation_type.rb比我不喜欢的更胖。
您没有明确说明任何目标或问题,这可能会帮助您获得更具体的答案。
答案 1 :(得分:0)
我最近一直在使用另一种方法。我们也不使用React,使用GraphQL::Relay::Mutation.define
来描述突变似乎很奇怪。
相反,我们描述了fields
。 (例如: app/graphql/mutations/create_owner.rb
)
Mutations::CreateOwner = GraphQL::Field.define do
name 'CreateOwner'
type Types::OwnerType
description 'Update owner attributes'
argument :name, !types.String
argument :description, types.String
resolve ->(_obj, args, _ctx) do
Owner.create!(args.to_h)
end
end
然后在 app/graphql/types/mutation_type.rb
中添加:
field :createOwner, Mutations::CreateOwner
可以通过将解析器提取到自己的解析器类中来进一步重构。
如果没有我能够找到的某些已定义的最佳实践,这是处理此问题的一种非常简洁的方法。
答案 2 :(得分:0)
您应该尝试https://github.com/samesystem/graphql_rails宝石。它在graphql端具有MVC结构,因此您的GraphQL将与您的RoR代码几乎相同。
如果我想要一个用于所有链接操作(CRUD)的唯一文件怎么办?
GraphqlRails使用控制器而不是解析器。您可能会遇到这样的事情:
.csv