forked from mirror/gorm
`UpdateColumns(...)` no longer triggers save of associated records.
This commit is contained in:
parent
7d16055a5d
commit
ab48cd222a
|
@ -360,7 +360,7 @@ db.Model(&user).Updates(User{Name: "hello", Age: 18})
|
|||
|
||||
### Update Without Callbacks
|
||||
|
||||
By default, update will call BeforeUpdate, AfterUpdate callbacks, if you want to update w/o callbacks:
|
||||
By default, update will call BeforeUpdate, AfterUpdate callbacks, if you want to update w/o callbacks and w/o saving associations:
|
||||
|
||||
```go
|
||||
db.Model(&user).UpdateColumn("name", "hello")
|
||||
|
|
|
@ -11,6 +11,9 @@ func CommitOrRollbackTransaction(scope *Scope) {
|
|||
}
|
||||
|
||||
func SaveBeforeAssociations(scope *Scope) {
|
||||
if !scope.shouldSaveAssociations() {
|
||||
return
|
||||
}
|
||||
for _, field := range scope.Fields() {
|
||||
if scope.changeableField(field) && !field.IsBlank && !field.IsIgnored {
|
||||
if relationship := field.Relationship; relationship != nil && relationship.Kind == "belongs_to" {
|
||||
|
@ -25,6 +28,9 @@ func SaveBeforeAssociations(scope *Scope) {
|
|||
}
|
||||
|
||||
func SaveAfterAssociations(scope *Scope) {
|
||||
if !scope.shouldSaveAssociations() {
|
||||
return
|
||||
}
|
||||
for _, field := range scope.Fields() {
|
||||
if scope.changeableField(field) && !field.IsBlank && !field.IsIgnored {
|
||||
if relationship := field.Relationship; relationship != nil &&
|
||||
|
|
1
main.go
1
main.go
|
@ -266,6 +266,7 @@ func (s *DB) UpdateColumn(attrs ...interface{}) *DB {
|
|||
func (s *DB) UpdateColumns(values interface{}) *DB {
|
||||
return s.clone().NewScope(s.Value).
|
||||
Set("gorm:update_column", true).
|
||||
Set("gorm:save_associations", false).
|
||||
InstanceSet("gorm:update_interface", values).
|
||||
callCallbacks(s.parent.callback.updates).db
|
||||
}
|
||||
|
|
8
scope.go
8
scope.go
|
@ -398,3 +398,11 @@ func (scope *Scope) changeableField(field *Field) bool {
|
|||
|
||||
return !field.IsIgnored
|
||||
}
|
||||
|
||||
func (scope *Scope) shouldSaveAssociations() bool {
|
||||
saveAssociations, ok := scope.Get("gorm:save_associations")
|
||||
if ok && !saveAssociations.(bool) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -382,3 +382,32 @@ func TestOmitWithUpdateColumn(t *testing.T) {
|
|||
t.Errorf("Should omit name column when update user")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateColumnsSkipsAssociations(t *testing.T) {
|
||||
user := getPreparedUser("update_columns_user", "special_role")
|
||||
user.Age = 99
|
||||
address1 := "first street"
|
||||
user.BillingAddress = Address{Address1: address1}
|
||||
DB.Save(user)
|
||||
|
||||
// Update a single field of the user and verify that the changed address is not stored.
|
||||
newAge := int64(100)
|
||||
user.BillingAddress.Address1 = "second street"
|
||||
db := DB.Model(user).UpdateColumns(User{Age: newAge})
|
||||
if db.RowsAffected != 1 {
|
||||
t.Errorf("Expected RowsAffected=1 but instead RowsAffected=%v", DB.RowsAffected)
|
||||
}
|
||||
|
||||
// Verify that Age now=`newAge`.
|
||||
freshUser := &User{Id: user.Id}
|
||||
DB.First(freshUser)
|
||||
if freshUser.Age != newAge {
|
||||
t.Errorf("Expected freshly queried user to have Age=%v but instead found Age=%v", newAge, freshUser.Age)
|
||||
}
|
||||
|
||||
// Verify that user's BillingAddress.Address1 is not changed and is still "first street".
|
||||
DB.First(&freshUser.BillingAddress, freshUser.BillingAddressID)
|
||||
if freshUser.BillingAddress.Address1 != address1 {
|
||||
t.Errorf("Expected user's BillingAddress.Address1=%s to remain unchanged after UpdateColumns invocation, but BillingAddress.Address1=%s", address1, freshUser.BillingAddress.Address1)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue