How can I append to a many-to-many relation in Gorm without upserting the already-existing associated rows?

Viewed 2715

How can I associate a model with already-existing other models in a many-to-many association without having GORM execute queries to UPSERT the already-existing models?

Example:

Suppose I have two GORM models in a many-to-many association with each other:

type A struct {
    ID int `gorm:"primaryKey"`
    Bs []B `gorm:"many2many:a_bs;"`
}

type B struct {
    ID int `gorm:"primaryKey"`
    As []A `gorm:"many2many:a_bs;"`
}

Suppose I create two As:

a1 := A{}
db.Create(&a1)

a2 := A{}
db.Create(&a2)

This will result in the following queries as expected:

INSERT INTO "as" DEFAULT VALUES RETURNING "id"
INSERT INTO "as" DEFAULT VALUES RETURNING "id"

And suppose I then want to create a B and associate it with the As:

b := B{
    As: []A{a1, a2},
}
db.Create(&b)

This will result in the following queries:

INSERT INTO "as" ("id") VALUES (3),(4) ON CONFLICT DO NOTHING RETURNING "id"
INSERT INTO "a_bs" ("b_id","a_id") VALUES (3,3),(3,4) ON CONFLICT DO NOTHING
INSERT INTO "bs" DEFAULT VALUES RETURNING "id"

How can I eliminate the first query, which unnecessarily upserts the already-inserted A models?

Using

b := B{}
db.Create(&b)
db.Model(&b).Association("As").Append([]A{a1, a2})

for the second bit of code instead has the same effect. Adding Omit("As") clauses will cancel the entire insertion.

1 Answers
Related