英文:
GraphQL Rails Update API getting `Types::ItemType#id`, which did not exist` error
问题
你有两个模型,Item和Artist,关系是Item属于Artist,而Artist有许多Items。
在app/models/item.rb文件中:
class Item < ApplicationRecord
belongs_to :artist
end
在app/models/artist.rb文件中:
class Artist < ApplicationRecord
has_many :items, dependent: :destroy
end
我创建了update_item.rb文件,放在app/graphql/update_item.rb中:
module Mutations
class UpdateItem < BaseMutation
type Types::ItemType
argument :id, ID, required: true
argument :title, String, required: true
argument :description, String, required: true
argument :image_url, String, required: true
argument :artist_id, ID, required: true
def resolve(id:, title:, description:, image_url:, artist_id:)
Item.find(id).update!(title: title, description: description, image_url: image_url, artist_id: artist_id)
end
end
end
在app/graphql/types/mutation_type.rb中定义其mutation类型:
module Types
class MutationType < Types::BaseObject
field :update_item, mutation: Mutations::UpdateItem
end
end
在GraphiQL web UI中写的mutation是:
mutation{
updateItem(input: {
id: 13,
title: "gfnm",
description: "vcbnm",
imageUrl: "fgehyerjfdbgh",
artistId: 8
}){
id
title
}
}
在数据库中已经更新了记录,但在rails服务器日志中出现上述错误。
英文:
I have two models Item and Artist, the relation is Item belongs to Artist and Artist has many Items.
app/models/item.rb
class Item < ApplicationRecord
belongs_to :artist
end
app/models/artist.rb
class Artist < ApplicationRecord
has_many :items, dependent: :destroy
end
I have created update_item.rb file inside app/graphql/update_item.rb
module Mutations
class UpdateItem < BaseMutation
type Types::ItemType
argument :id, ID, required: true
argument :title, String, required: true
argument :description, String, required: true
argument :image_url, String, required: true
argument :artist_id, ID, required: true
def resolve(id:,title:,description:,image_url:, artist_id:)
Item.find(id).update!(title: title, description: description, image_url: image_url, artist_id: artist_id)
end
end
end
define its mutation type in app/graphql/types/mutation_type.rb
module Types
class MutationType < Types::BaseObject
field :update_item, mutation: Mutations::UpdateItem
end
end
Mutatin which we have written in GraphiQL web UI is -
mutation{
updateItem(input: {
id: 13,
title: "gfnm",
description: "vcbnm",
imageUrl: "fgehyerjfdbgh",
artistId: 8
}){
id
title
}
}
it has been updated the record in the database but after that getting error in the rails server log below -
Failed to implement Item.id, tried:
- `Types::ItemType#id`, which did not exist
- `TrueClass#id`, which did not exist
- Looking up hash key `:id` or `"id"` on `true`, but it wasn't a Hash
To implement this field, define one of the methods above (and check for typos), or supply a `fallback_value`.
Could anyone please help me why getting the above error after updating the record?
答案1
得分: 1
According to these data in the GQL request,
{
id
title
}
it is expected that those fields (id
and title
) will be returned after the mutation is executed.
But there are no such fields defined in your mutation. What your mutation returns is the result of the resolve
method, which is the result of the update!
call, which is true
. That's why you see the TrueClass#id, which did not exist
error. It cannot extract the id
and title
fields from true
.
The fields that you want to be returned must be listed with the field
method. The result of the resolve
method should be a hash including those fields.
module Mutations
class UpdateItem < BaseMutation
type Types::ItemType
argument :id, ID, required: true
# ... The rest of arguments
field :id, ID, null: false
field :title, String, null: false
def resolve(id:,title:,description:,image_url:, artist_id:)
item = Item.find(id)
item.update!(title: title, description: description, image_url: image_url, artist_id: artist_id)
{
id: item.id,
title: item.title
}
end
end
end
Here is another suggestion. As the best practice, the result of the mutation should be the updated record:
module Mutations
class UpdateItem < BaseMutation
# ...
field :item, Types::ItemType, null: false
def resolve(id:,title:,description:,image_url:, artist_id:)
item = Item.find(id)
item.update!(title: title, description: description, image_url: image_url, artist_id: artist_id)
{
item: item
}
end
end
end
Front-end:
mutation{
updateItem(input: {
id: 13,
title: "gfnm",
description: "vcbnm",
imageUrl: "fgehyerjfdbgh",
artistId: 8
}){
item { # requesting the updated record !!!
id
title
}
}
}
One more thing for you to figure out is how to handle error cases.
英文:
According to these data in the GQL request,
{
id
title
}
it is expected that those fields (id
and title
) will be returned after the mutation is executed.
But there are no such fields defined in your mutation. What your mutation returns is the result of the resolve
method, which is the result of the update!
call, which is true
. That's why you see the
TrueClass#id, which did not exist
error. It cannot extract the id
and title
fields from true
.
The fields that you want to be returned must be listed with the field
method. The result of the resolve
method should be a hash including those fields.
module Mutations
class UpdateItem < BaseMutation
type Types::ItemType
argument :id, ID, required: true
# ... The rest of arguments
field :id, ID, null: false
field :title, String, null: false
def resolve(id:,title:,description:,image_url:, artist_id:)
item = Item.find(id)
item.update!(title: title, description: description, image_url: image_url, artist_id: artist_id)
{
id: item.id,
title: item.title
}
end
end
end
Here is another suggestion. As the best practice, the result of the mutation should be the updated record:
module Mutations
class UpdateItem < BaseMutation
# ...
field :item, Types::ItemType, null: false
def resolve(id:,title:,description:,image_url:, artist_id:)
item = Item.find(id)
item.update!(title: title, description: description, image_url: image_url, artist_id: artist_id)
{
item: item
}
end
end
end
Front-end:
mutation{
updateItem(input: {
id: 13,
title: "gfnm",
description: "vcbnm",
imageUrl: "fgehyerjfdbgh",
artistId: 8
}){
item { # requesting the updated record !!!
id
title
}
}
}
One more thing for you to figure out is how to handle error cases.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论