diff --git a/association_test.go b/association_test.go index c84f84ed..f37047d1 100644 --- a/association_test.go +++ b/association_test.go @@ -902,6 +902,20 @@ func TestSkipSaveAssociation(t *testing.T) { DB.Save(&User{Name: "jinzhu", Company: Company{Name: "skip_save_association"}}) if !DB.Where("name = ?", "skip_save_association").First(&Company{}).RecordNotFound() { - t.Errorf("Company skip_save_association should not been saved") + t.Errorf("Company skip_save_association should not have been saved") + } + + // if foreign key is set, this should be saved even if association isn't + company := Company{Name: "skip_save_association"} + DB.Save(&company) + company.Name = "skip_save_association_modified" + user := User{Name: "jinzhu", CompanyID: company.ID, Company: company} + DB.Save(&user) + + if !DB.Where("name = ?", "skip_save_association_modified").First(&Company{}).RecordNotFound() { + t.Errorf("Company skip_save_association should not have been updated") + } + if DB.Where("id = ? AND company_id = ?", user.ID, company.ID).First(&User{}).RecordNotFound() { + t.Errorf("User's foreign key should have been saved") } } diff --git a/callback_save.go b/callback_save.go index f4bc918e..fa32c907 100644 --- a/callback_save.go +++ b/callback_save.go @@ -13,22 +13,21 @@ func commitOrRollbackTransactionCallback(scope *Scope) { func saveFieldAsAssociation(scope *Scope, field *Field) (bool, *Relationship) { if scope.changeableField(field) && !field.IsBlank && !field.IsIgnored { if value, ok := field.TagSettings["SAVE_ASSOCIATIONS"]; !ok || (value != "false" && value != "skip") { - if relationship := field.Relationship; relationship != nil { - return true, relationship - } + return true, field.Relationship } + return false, field.Relationship } return false, nil } func saveBeforeAssociationsCallback(scope *Scope) { - if !scope.shouldSaveAssociations() { - return - } for _, field := range scope.Fields() { - if ok, relationship := saveFieldAsAssociation(scope, field); ok && relationship.Kind == "belongs_to" { + ok, relationship := saveFieldAsAssociation(scope, field) + if relationship != nil && relationship.Kind == "belongs_to" { fieldValue := field.Field.Addr().Interface() - scope.Err(scope.NewDB().Save(fieldValue).Error) + if ok && scope.shouldSaveAssociations() { + scope.Err(scope.NewDB().Save(fieldValue).Error) + } if len(relationship.ForeignFieldNames) != 0 { // set value's foreign key for idx, fieldName := range relationship.ForeignFieldNames { @@ -47,7 +46,7 @@ func saveAfterAssociationsCallback(scope *Scope) { return } for _, field := range scope.Fields() { - if ok, relationship := saveFieldAsAssociation(scope, field); ok && + if ok, relationship := saveFieldAsAssociation(scope, field); ok && relationship != nil && (relationship.Kind == "has_one" || relationship.Kind == "has_many" || relationship.Kind == "many_to_many") { value := field.Field