Как я могу добавить к отношению «многие ко многим» в Gorm, не перенося уже существующие связанные строки?

#go #orm #go-gorm

#Вперед #orm #go-gorm

Вопрос:

Как я могу связать модель с уже существующими другими моделями в ассоциации «многие ко многим», не заставляя GORM выполнять запросы для обновления уже существующих моделей?

Пример:

Предположим, у меня есть две модели GORM, связанные друг с другом по принципу «многие ко многим»:

 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;"`
}
  

Предположим, я создаю два как:

 a1 := A{}
db.Create(amp;a1)

a2 := A{}
db.Create(amp;a2)
  

Это приведет к следующим запросам, как и ожидалось:

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

И предположим, что затем я хочу создать B и связать его с As:

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

Это приведет к следующим запросам:

 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"
  

Как я могу исключить первый запрос, который излишне увеличивает уже вставленные модели A?

Используя

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

для второго бита кода вместо этого имеет тот же эффект. Добавление предложений Omit(«As») отменит всю вставку.

Ответ №1:

 db.Omit("As.*").Create(amp;b)
  

В ассоциациях gorm есть примечание: пропустить документы для автоматического создания / обновления, в которых это подробно описано. Это легко пропустить.