Auto Create/Update

GORM will auto-save associations and its reference using Upsert when creating/updating a record.

user := User{
Name: "jinzhu",
BillingAddress: Address{Address1: "Billing Address - Address 1"},
ShippingAddress: Address{Address1: "Shipping Address - Address 1"},
Emails: []Email{
{Email: ""},
{Email: ""},
Languages: []Language{
{Name: "ZH"},
{Name: "EN"},

// INSERT INTO "addresses" (address1) VALUES ("Billing Address - Address 1"), ("Shipping Address - Address 1") ON DUPLICATE KEY DO NOTHING;
// INSERT INTO "users" (name,billing_address_id,shipping_address_id) VALUES ("jinzhu", 1, 2);
// INSERT INTO "emails" (user_id,email) VALUES (111, ""), (111, "") ON DUPLICATE KEY DO NOTHING;
// INSERT INTO "languages" ("name") VALUES ('ZH'), ('EN') ON DUPLICATE KEY DO NOTHING;
// INSERT INTO "user_languages" ("user_id","language_id") VALUES (111, 1), (111, 2) ON DUPLICATE KEY DO NOTHING;


Skip Auto Create/Update

To skip the auto save when creating/updating, you can use Select or Omit, for example:

user := User{
Name: "jinzhu",
BillingAddress: Address{Address1: "Billing Address - Address 1"},
ShippingAddress: Address{Address1: "Shipping Address - Address 1"},
Emails: []Email{
{Email: ""},
{Email: ""},
Languages: []Language{
{Name: "ZH"},
{Name: "EN"},

// INSERT INTO "users" (name) VALUES ("jinzhu", 1, 2);

// Skip create BillingAddress when creating a user

// Skip all associations when creating a user

Association Mode

Association Mode contains some commonly used helper methods to handle relationships

// Start Association Mode
var user User
// `user` is the source model, it must contains primary key
// `Languages` is a relationship's field name
// If the above two requirements matched, the AssociationMode should be started successfully, or it should return error

Find Associations

Find matched associations


Find associations with conditions

codes := []string{"zh-CN", "en-US", "ja-JP"}
db.Model(&user).Where("code IN ?", codes).Association("Languages").Find(&languages)

db.Model(&user).Where("code IN ?", codes).Order("code desc").Association("Languages").Find(&languages)

Append Associations

Append new associations for many to many, has many, replace current association for has one, belongs to

db.Model(&user).Association("Languages").Append([]Language{languageZH, languageEN})

db.Model(&user).Association("Languages").Append(Language{Name: "DE"})

db.Model(&user).Association("CreditCard").Append(CreditCard{Number: "411111111111"})

Replace Associations

Replace current associations with new ones

db.Model(&user).Association("Languages").Replace([]Language{languageZH, languageEN})

db.Model(&user).Association("Languages").Replace(Language{Name: "DE"}, languageEN)

Delete Associations

Remove the relationship between source & arguments if exists, only delete the reference, won’t delete those objects from DB.

db.Model(&user).Association("Languages").Delete([]Language{languageZH, languageEN})
db.Model(&user).Association("Languages").Delete(languageZH, languageEN)

Clear Associations

Remove all reference between source & association, won’t delete those associations


Count Associations

Return the count of current associations


// Count with conditions
codes := []string{"zh-CN", "en-US", "ja-JP"}
db.Model(&user).Where("code IN ?", codes).Association("Languages").Count()

Batch Data

Association Mode supports batch data, e.g:

// Find all roles for all users

// Delete User A from all users's team

// Get unduplicated count of members in all user's team

// For `Append`, `Replace` with batch data, arguments's length need to equal to data's length or will return error
var users = []User{user1, user2, user3}
// e.g: we have 3 users, Append userA to user1's team, append userB to user2's team, append userA, userB and userC to user3's team
db.Model(&users).Association("Team").Append(&userA, &userB, &[]User{userA, userB, userC})
// Reset user1's team to userA,reset user2's team to userB, reset user3's team to userA, userB and userC
db.Model(&users).Association("Team").Replace(&userA, &userB, &[]User{userA, userB, userC})

Delete with Select

You are allowed to delete selected has one/has many/many2many relations with Select when deleting records, for example:

// delete user's account when deleting user

// delete user's Orders, CreditCards relations when deleting user
db.Select("Orders", "CreditCards").Delete(&user)

// delete user's has one/many/many2many relations when deleting user

// delete users's account when deleting users

Association Tags

Tag Description
foreignKey Specifies foreign key
references Specifies references
polymorphic Specifies polymorphic type
polymorphicValue Specifies polymorphic value, default table name
many2many Specifies join table name
joinForeignKey Specifies foreign key of jointable
joinReferences Specifies references’ foreign key of jointable
constraint Relations constraint, e.g: OnUpdate,OnDelete