How to resolve a Graphql Union with Gorm?

huangapple go评论83阅读模式
英文:

How to resolve a Graphql Union with Gorm?

问题

我有两个具体类型ProdottoProdottoVariante,它们都实现了类型为Articolo的接口。

union Articoli = Prodotto | ProdottoVariante

extend type Query {
  articoli: [Articoli!]!
}

我想通过键入articoli来查询所有的Prodotto和ProdottoVariante,但我不知道如何解析Articoli

我尝试了以下方法:

func (r *queryResolver) Articoli(ctx context.Context) ([]model.Articoli, error) {
    var articoli []model.Articoli

    r.DB.Model(&model.Prodotto{}).Select("nome").Find(&articoli)
    r.DB.Model(&model.ProdottoVariante{}).Select("nome").Find(&articoli)

    return articoli, nil
}

我这样查询:

query {
  articoli {
    __typename
    ...on Prodotto {
      nome
    }
  }
}

但是我得到了这个错误:

{
  "errors": [
    {
      "message": "must not be null",
      "path": [
        "articoli",
        0
      ]
    }
  ],
  "data": null
}
sql: Scan error on column index 0, name "nome": unsupported Scan, storing driver.Value type string into type *model.Articoli

如何正确解析使用gorm的联合类型?

英文:

I have a union on two concrete types Prodotto and ProdottoVariante both implements a interface of type Articolo.

union Articoli = Prodotto | ProdottoVariante

extend type Query {
  articoli: [Articoli!]!
}

I want to query all Prodotto and all ProdottoVariante by typing articoli but I don't know how to resolve Articoli

I'm trying in this way:

func (r *queryResolver) Articoli(ctx context.Context) ([]model.Articoli, error) {
	var articoli []model.Articoli

	r.DB.Model(&model.Prodotto{}).Select("nome").Find(&articoli)
	r.DB.Model(&model.ProdottoVariante{}).Select("nome").Find(&articoli)

	return articoli, nil
}

and I'm querying in this way:

query {
  articoli {
    __typename
    ...on Prodotto {
      nome
    }
  }
}

but I get this error:

{
  "errors": [
    {
      "message": "must not be null",
      "path": [
        "articoli",
        0
      ]
    }
  ],
  "data": null
}
sql: Scan error on column index 0, name "nome": unsupported Scan, storing driver.Value type string into type *model.Articoli

How to correctly resolve Unions with gorm?

答案1

得分: 1

你可以尝试在prodottoprodotto_variante表之间创建一个连接,并选择所需的列来填充Articoli结构体中的字段。

我不确定你的prodottoprodotto_variante表之间的关系。我还假设nome列是prodotto表的一部分,并且它对应于Articoli结构体中的一个字段。代码应该如下所示:

func (r *queryResolver) Articoli(ctx context.Context) ([]model.Articoli, error) {
    var articoli []model.Articoli

    err := r.DB.Table("prodottos").
               Join("JOIN prodotto_variantes pv ON prodotto.id = pv.prodotto_id").
               Find(&articoli).Error

    return articoli, err
}

上述代码应该填充整个Articoli结构体,如果结构体字段与prodottos表中的列匹配。

如果你只想填充部分字段,可以有两种方法。

示例1

// 如果要填充多个字段,可以尝试以下代码
err := r.DB.Table("prodottos").
               Join("JOIN prodotto_variantes pv ON prodotto.id = pv.prodotto_id").
               Select("prodottos.id, prodottos.nome").
               Find(&articoli).Error

示例2

// 如果只想填充一个字段,可以尝试以下代码
type Art struct {
   Nome string
}
var arts []Art
err := r.DB.Table("prodottos").
               Join("JOIN prodotto_variantes pv ON prodotto.id = pv.prodotto_id").
               Find(&arts).Error
英文:

You could always try to create a join between prodotto and prodotto_variante tables and select the needed columns to populate the fields in the Articoli struct.

I'm not sure how your prodotto and prodotto_variante tables relate to each other. I'm also assuming that the nome column is part of the prodotto table and that it corresponds to a field in the Articoli struct. The code would look something like this:

func (r *queryResolver) Articoli(ctx context.Context) ([]model.Articoli, error) {
    var articoli []model.Articoli

    err:= r.DB.Table("prodottos").
               Join("JOIN prodotto_variantes pv ON prodotto.id = pv.prodotto_id").
               Find(&articoli).Error

    return articoli, err
}

The above code should populate the entire Articoli struct, if the struct fields match the columns in the prodottos table.

If you want to populate just some of the fields, you can do it in a couple of ways.

Example 1

// this should work if populating more than one field
err:= r.DB.Table("prodottos").
                   Join("JOIN prodotto_variantes pv ON prodotto.id = pv.prodotto_id").
                   Select("prodottos.id, prodottos.nome").
                   Find(&articoli).Error

Example 2

// this should work if you want to populate only one field
type Art struct {
   Nome string
}
var arts []Art
err:= r.DB.Table("prodottos").
                   Join("JOIN prodotto_variantes pv ON prodotto.id = pv.prodotto_id").
                   Find(&arts).Error

huangapple
  • 本文由 发表于 2022年1月31日 16:38:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/70923136.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定