Итак, у меня есть вот эта модель плеера:
package models
// Player defines a player for the app
type Player struct {
BaseModelSoftDelete
Name *string
Nickname *string
ThrowCount *int
InGame *bool
// Belongs to one
GameID *int
// Has one
Image Image
X01Score X01Score
Podium Podium
// Has many
Rounds []Round
}
И у меня работает GraphQL с этой схемой:
type Player {
id: ID!
name: String!
nickname: String
throwCount: Int
inGame: Boolean
gameId: ID
game: Game
image: Image
x01score: X01Score
podium: Podium
rounds: [Round]
}
type Query {
playerList: [Player]
player(id: ID!): Player
}
GraphQL используется для представления моих данных. У меня есть два типа преобразователей запросов. Преобразователь списков, который должен возвращать список, который работает следующим образом:
func (r *queryResolver) PlayerList(_ context.Context) ([]*models.Player, error) {
var players []*models.Player
r.ORM.DB.Preload("Game").Preload("Image").Preload("Podium").Preload("X01score").Preload("Rounds").Preload("Rounds.Throws").Find(&players)
return players, nil
}
Посмотрите, как переменная player является срезом типа models.Player? И возвращаемое значение тоже единица? Все идет нормально. Это вернет моих игроков, как и предполагалось.
Теперь у меня есть второй тип, который должен возвращать одного игрока в зависимости от его ID:
func (r *queryResolver) Player(_ context.Context, id int) (*models.Player, error) {
var player *models.Player
r.ORM.DB.Preload("Image").Preload("X01score").Preload("Game").Preload("Podium").First(&player, id)
return player, nil
}
Посмотрите, как gqlgen определил возвращаемое значение быть единственным экземпляром models.Player? Также я определяю переменную как единственный экземпляр и возвращаю ее. Ну, код будет скомпилирован, но если я запрошу игрока с идентификатором 1 (игрок находится в базе данных, я проверил его с помощью браузера sqlite), он вернет ошибку, которая гласит:
unsupported destination, should be slice or struct
в строке, запрашивающей игрока -> ... First (& player, id)
Итак, я могу обойти проблему, определив схему следующим образом:
type Query {
playerList: [Player]
player(id: ID!): [Player]
}
Я изменил запрос плеера, чтобы он возвращал массив в определении схемы. Затем определите преобразователь следующим образом:
func (r *queryResolver) Player(_ context.Context, id int) ([]*models.Player, error) {
var player []*models.Player
r.ORM.DB.Preload("Image").Preload("X01score").Preload("Game").Preload("Podium").First(&player, id)
return player, nil
}
Измененная переменная на срез, а также возвращаемое значение. Gorm запросит только одно возвращаемое значение (причина ... First (& player, id)) из базы данных и упакует его в фрагмент всего с одной записью.
Мне это кажется неправильным. Как я могу решить эту проблему?
С уважением и наилучшими пожеланиями, Патрик
Решение, приведенное в предложении ниже:
Спасибо, Саймон С.
func (r *queryResolver) Player(_ context.Context, id int) (*models.Player, error) {
var player models.Player
r.ORM.DB.Preload("Image").Preload("X01score").Preload("Game").Preload("Podium").First(player, id)
return &player, nil