postgresqlgopostmanmany-to-manygo-gorm

GORM don't create many2many associations


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


Solution

  • 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
    }