Home > Mobile >  GORM don't create many2many associations
GORM don't create many2many associations

Time:06-24

I have model:

type Book struct {
    gorm.Model
    Title       string `json:"title"`
    Author      string `json:"author"`
    Description string `json:"description"`
    Category    string `json:"Category"`
    Publisher   string `json:"publisher"`
    AuthorsCard []*AuthorsCard `gorm:"many2many:book_authorscard; "json:"authorscard"`
}

type AuthorsCard struct {
    gorm.Model
    Name        string `json:"name"`
    Age         int    `json:"age"`
    YearOfBirth int    `json:"year"`
    Biography   string `json:"biography"`
}

After db.AutoMigrate(&models.Book{}, &models.AuthorsCard{})
I have a creation function:

func TestCreate() {
    var testbook = models.Book{
        Title:  "Test",
        Author: "tst",
        AuthorsCard: []*models.AuthorsCard{
            {
                Age:         23,
                Name:        "test",
                YearOfBirth: 1999,
                Biography:   "23fdgsdddTEST",
            },
        },
        Description: "something",
    }
    db.Preload("AuthorsCard").Find(&models.Book{})

    db.Create(&testbook)

}

despite That AuthorsCard has some data in it, I receive this as a response:

{
        "ID": 78,
        "CreatedAt": "2022-06-23T13:10:58.01629 03:00",
        "UpdatedAt": "2022-06-23T13:10:58.01629 03:00",
        "DeletedAt": null,
        "title": "Test",
        "author": "tst",
        "description": "something",
        "Category": "",
        "publisher": "",
        "authorscard": null
    }

As you can see "authorscard" is null.

How can I save "authorscard" to the database? I used Gorm postgresql and also I sent a few request with postman, results are the same - Authors card is null

CodePudding user response:

The code is working when it's called in the correct order:

func TestCreate() {
    db := getDB()
    db.AutoMigrate(&Book{}, AuthorsCard{})

    var testbook = Book{
        Title:  "Test",
        Author: "tst",
        AuthorsCard: []*AuthorsCard{
            {
                Age:         23,
                Name:        "test",
                YearOfBirth: 1999,
                Biography:   "23fdgsdddTEST",
            },
        },
        Description: "something",
    }

    // 1. Create your testbook.
    db.Create(&testbook)

    // 2. Store it into a variable:
    var b1 *Book
    db.Preload("AuthorsCard").Find(&b1)
    
    fmt.Println(b1.AuthorsCard[0].Age)
    fmt.Println(b1.AuthorsCard[0].Name)
    fmt.Println(b1.AuthorsCard[0].YearOfBirth)
    fmt.Println(b1.AuthorsCard[0].Biography)

}

prints:

23 test 1999 23fdgsdddTEST

Also your JSON export might fail since you pass a pointer to AuthorCard and the marshalling not always works properly in those cases. However, GORM does the right job here.

Static check also gave me some hints here:

type Book struct {
    gorm.Model
    Title       string         `json:"title"`
    Author      string         `json:"author"`
    Description string         `json:"description"`
    Category    string         `json:"Category"`
    Publisher   string         `json:"publisher"`
    AuthorsCard []*AuthorsCard `gorm:"many2many:book_authorscard" json:"authorscard"` // wrong space
}
  • Related