Make Updates accept struct other than map[string]interface{}

This commit is contained in:
Jinzhu 2013-10-31 08:29:57 +08:00
parent 688e992266
commit 31b4baba6f
4 changed files with 25 additions and 4 deletions

View File

@ -219,6 +219,12 @@ db.Table("users").Where(10).Updates(map[string]interface{}{"name": "hello", "age
//// update users set name='hello', age=18 where id = 10; //// update users set name='hello', age=18 where id = 10;
db.Table("users").Updates(map[string]interface{}{"name": "hello", "age": 18}) db.Table("users").Updates(map[string]interface{}{"name": "hello", "age": 18})
//// update users set name='hello', age=18; //// update users set name='hello', age=18;
db.Find(&users).Updates(User{Name: "hello", Age: 18})
//// update users set name='hello', age=18;
db.First(&user, 20).Updates(User{Name: "hello", Age: 18})
//// update users set name='hello', age=18 where id = 20;
//// object user's value would be reflected by the Updates also,
//// so you don't need to refetch the user from database
// Soft Delete // Soft Delete
// For those struct have DeletedAt field, they will get soft delete ability automatically! // For those struct have DeletedAt field, they will get soft delete ability automatically!

View File

@ -157,7 +157,7 @@ func (s *Chain) Update(column string, value interface{}) *Chain {
return s.Updates(map[string]interface{}{column: value}, true) return s.Updates(map[string]interface{}{column: value}, true)
} }
func (s *Chain) Updates(values map[string]interface{}, ignore_protected_attrs ...bool) *Chain { func (s *Chain) Updates(values interface{}, ignore_protected_attrs ...bool) *Chain {
s.do(s.value).setUpdateAttrs(values, ignore_protected_attrs...).update() s.do(s.value).setUpdateAttrs(values, ignore_protected_attrs...).update()
return s return s
} }

16
do.go
View File

@ -146,8 +146,20 @@ func (s *Do) create() {
return return
} }
func (s *Do) setUpdateAttrs(values map[string]interface{}, ignore_protected_attrs ...bool) *Do { func (s *Do) setUpdateAttrs(values interface{}, ignore_protected_attrs ...bool) *Do {
s.updateAttrs = values switch values.(type) {
case map[string]interface{}:
s.updateAttrs = values.(map[string]interface{})
case interface{}:
m := &Model{data: values, driver: s.driver}
fields := m.columnsHasValue("")
s.updateAttrs = make(map[string]interface{}, len(fields))
for _, field := range fields {
s.updateAttrs[field.DbName] = field.Value
}
}
s.ignoreProtectedAttrs = len(ignore_protected_attrs) > 0 && ignore_protected_attrs[0] s.ignoreProtectedAttrs = len(ignore_protected_attrs) > 0 && ignore_protected_attrs[0]
return s return s
} }

View File

@ -778,7 +778,10 @@ func TestUpdates(t *testing.T) {
updated_at2 := product2.UpdatedAt updated_at2 := product2.UpdatedAt
var product3 Product var product3 Product
db.First(&product3, product2.Id).Updates(map[string]interface{}{"code": "edf", "price": 100}) db.First(&product3, product2.Id).Updates(Product{Code: "edf", Price: 100})
if product3.Code != "edf" || product3.Price != 100 {
t.Errorf("Object should be updated also with update attributes")
}
if updated_at2.Format(time.RFC3339Nano) != product3.UpdatedAt.Format(time.RFC3339Nano) { if updated_at2.Format(time.RFC3339Nano) != product3.UpdatedAt.Format(time.RFC3339Nano) {
t.Errorf("updated_at should not be updated if nothing really new") t.Errorf("updated_at should not be updated if nothing really new")