go-gorm / gorm

The fantastic ORM library for Golang, aims to be developer friendly
https://gorm.io
MIT License
36.58k stars 3.91k forks source link

How to define []string in Gorm Model #4498

Closed Urento closed 3 years ago

Urento commented 3 years ago

I have been trying to define a []string in a Gorm Model looking like this

type Shoppinglist struct {
    Model

    Title        string
    Items        []string
    Owner        string
    Participants []string
}

My Model struct looks like this:

type Model struct {
    ID         int `gorm:"private_key" json:"id"`
    CreatedOn  int `gorm:"autoCreateTime" json:"created_on"`
    ModifiedOn int `gorm:"autoUpdateTime:milli" json:"modified_on"`
}

When I try to AutoMigrate it like this: db.AutoMigrate(&Shoppinglist{})

I get an error:

unsupported data type: &[]

And I think its the []string because I can't find it in an example in the documentation. I would highly appreciate any help!

The document you expected this should be explained

I'd expect it to be explained in https://gorm.io/docs/models.html

Expected answer

I want to know if something is wrong with my Model and if, what? E.g. is it the []string or is it something completly different. And if it is the []string how do I store an Array?

Urento commented 3 years ago

I also got this error

failed to parse value &models.Shoppinglist{Model:models.Model{ID:0, CreatedOn:0, ModifiedOn:0}, Title:"", Items:[]string(nil), Owner:"", Participants:[]string(nil)}, got error unsupported data type: &[]

Urento commented 3 years ago

This is the test i wrote (I am very new to Go btw):

func TestCreate(t *testing.T) {
    Setup()

    id := rand.Intn(10000)
    title := StringWithCharset(20)
    items := []string{StringWithCharset(45), StringWithCharset(45), StringWithCharset(45), StringWithCharset(45)}
    owner := StringWithCharset(30)
    participants := []string{StringWithCharset(45), StringWithCharset(45), StringWithCharset(45), StringWithCharset(45)}
    shoppinglist := Shoppinglist{
        ID:           id,
        Title:        title,
        Items:        items,
        Owner:        owner,
        Participants: participants,
    }
    err := shoppinglist.Create()
    if err != nil {
        fmt.Println(err.Error())
        t.Errorf("Failed to create shoppinglist")
    }

    list := Shoppinglist{ID: id}
    exists, err := list.ExistsByID()
    if err != nil || !exists {
        t.Errorf("Shoppinglist did not get created")
    }

    l, err := list.GetList()
    if err != nil {
        t.Errorf("Shoppinglist not found")
    }

    if l.ID != id || !testEq(l.Items, items) || l.Owner != owner || !testEq(l.Participants, participants) || l.Title != title {
        t.Errorf("Values weren't correct ")
    }

    err = list.Delete()
    if err != nil {
        t.Errorf("Unable to delete the list")
    }

}

The Error gets thrown from by the Create Method

func (s *Shoppinglist) Create() error {
    shoppinglist := map[string]interface{}{
        "id":           s.ID,
        "title":        s.Title,
        "items":        s.Items,
        "owner":        s.Owner,
        "participants": s.Participants,
    }

    if err := models.CreateList(shoppinglist); err != nil {
        log.Fatal(err.Error())
        return err
    }

    return nil
}
func CreateList(data map[string]interface{}) error {
    list := Shoppinglist{
        Title:        data["title"].(string),
        Items:        data["items"].([]string),
        Owner:        data["owner"].(string),
        Participants: data["participants"].([]string),
    }
    if err := db.Create(&list).Error; err != nil {
        return err
    }
    return nil
}
Urento commented 3 years ago

Got it to work when I changed the string[] to pq.StringArray gorm:"type:text[]"

mike-lloyd03 commented 1 year ago

Got it to work when I changed the string[] to pq.StringArray gorm:"type:text[]"

Is this documented anywhere? Spent a lot of time trying to find this answer.

zbysir commented 1 year ago

Got it to work when I changed the string[] to pq.StringArray gorm:"type:text[]"

Is this documented anywhere? Spent a lot of time trying to find this answer.

Me too, the docs are a bit rotten. It would be better if the error message was accompanied by suggestions, such as 'maybe you need to add type definition to the tag'

jinzhu commented 1 year ago

Got it to work when I changed the string[] to pq.StringArray gorm:"type:text[]"

Is this documented anywhere? Spent a lot of time trying to find this answer.

https://gorm.io/docs/serializer.html

zbysir commented 1 year ago

Got it to work when I changed the string[] to pq.StringArray gorm:"type:text[]"

Is this documented anywhere? Spent a lot of time trying to find this answer.

https://gorm.io/docs/serializer.html

Hi~ @jinzhu, Guess which one of them works?

  1. pq.StringArray

    type Post struct {
    Title  string
    Tags   pq.StringArray
    }
  2. pq.StringArray and type

    type Post struct {
    Title  string
    Tags   pq.StringArray `gorm:"type:text[]"`
    }
  3. []string and type

    type Post struct {
    Title  string
    Tags   []string `gorm:"type:text[]"`
    }
  4. []string and serializer

    type Post struct {
    Title  string
    Tags   []string `gorm:"serializer:json"`
    }
  5. []string and serializer and type

    type Post struct {
    Title  string
    Tags   []string `gorm:"type:text[]; serializer:json"`
    }

If they both work, which one is better to use?

nielskrijger commented 2 days ago

It is indeed very confusing. Tohe only one that worked for me was Tags pq.StringArray gorm:"type:text[]"

Since the pq library is in maintenance mode, is there any pgx equivalent? Or some way to make it work with plain []string?