mirror of https://github.com/go-gorm/gorm.git
Merge pull request #438 from jaytaylor/jay/update-columns-skip-associations
Skip saving associations during UpdateColumns(...)
This commit is contained in:
commit
14620058ed
|
@ -360,7 +360,7 @@ db.Model(&user).Updates(User{Name: "hello", Age: 18})
|
||||||
|
|
||||||
### Update Without Callbacks
|
### 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
|
```go
|
||||||
db.Model(&user).UpdateColumn("name", "hello")
|
db.Model(&user).UpdateColumn("name", "hello")
|
||||||
|
|
|
@ -11,6 +11,9 @@ func CommitOrRollbackTransaction(scope *Scope) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func SaveBeforeAssociations(scope *Scope) {
|
func SaveBeforeAssociations(scope *Scope) {
|
||||||
|
if !scope.shouldSaveAssociations() {
|
||||||
|
return
|
||||||
|
}
|
||||||
for _, field := range scope.Fields() {
|
for _, field := range scope.Fields() {
|
||||||
if scope.changeableField(field) && !field.IsBlank && !field.IsIgnored {
|
if scope.changeableField(field) && !field.IsBlank && !field.IsIgnored {
|
||||||
if relationship := field.Relationship; relationship != nil && relationship.Kind == "belongs_to" {
|
if relationship := field.Relationship; relationship != nil && relationship.Kind == "belongs_to" {
|
||||||
|
@ -25,6 +28,9 @@ func SaveBeforeAssociations(scope *Scope) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func SaveAfterAssociations(scope *Scope) {
|
func SaveAfterAssociations(scope *Scope) {
|
||||||
|
if !scope.shouldSaveAssociations() {
|
||||||
|
return
|
||||||
|
}
|
||||||
for _, field := range scope.Fields() {
|
for _, field := range scope.Fields() {
|
||||||
if scope.changeableField(field) && !field.IsBlank && !field.IsIgnored {
|
if scope.changeableField(field) && !field.IsBlank && !field.IsIgnored {
|
||||||
if relationship := field.Relationship; relationship != nil &&
|
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 {
|
func (s *DB) UpdateColumns(values interface{}) *DB {
|
||||||
return s.clone().NewScope(s.Value).
|
return s.clone().NewScope(s.Value).
|
||||||
Set("gorm:update_column", true).
|
Set("gorm:update_column", true).
|
||||||
|
Set("gorm:save_associations", false).
|
||||||
InstanceSet("gorm:update_interface", values).
|
InstanceSet("gorm:update_interface", values).
|
||||||
callCallbacks(s.parent.callback.updates).db
|
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
|
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")
|
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