Update with Select and Omit

This commit is contained in:
Jinzhu 2015-03-12 18:30:59 +08:00
parent 5d52826b3d
commit 187eae8d9c
6 changed files with 84 additions and 9 deletions

View File

@ -26,7 +26,7 @@ func Create(scope *Scope) {
var sqls, columns []string
fields := scope.Fields()
for _, field := range fields {
if scope.ValidField(field) {
if scope.changeableField(field) {
if field.IsNormal {
if !field.IsPrimaryKey || (field.IsPrimaryKey && !field.IsBlank) {
if !field.IsBlank || !field.HasDefaultValue {
@ -35,7 +35,7 @@ func Create(scope *Scope) {
}
}
} else if relationship := field.Relationship; relationship != nil && relationship.Kind == "belongs_to" {
if relationField := fields[relationship.ForeignDBName]; !scope.ValidField(relationField) {
if relationField := fields[relationship.ForeignDBName]; !scope.changeableField(relationField) {
columns = append(columns, scope.Quote(relationField.DBName))
sqls = append(sqls, scope.AddToVars(relationField.Field.Interface()))
}

View File

@ -12,7 +12,7 @@ func CommitOrRollbackTransaction(scope *Scope) {
func SaveBeforeAssociations(scope *Scope) {
for _, field := range scope.Fields() {
if scope.ValidField(field) && !field.IsBlank && !field.IsIgnored {
if scope.changeableField(field) && !field.IsBlank && !field.IsIgnored {
if relationship := field.Relationship; relationship != nil && relationship.Kind == "belongs_to" {
value := field.Field
scope.Err(scope.NewDB().Save(value.Addr().Interface()).Error)
@ -26,7 +26,7 @@ func SaveBeforeAssociations(scope *Scope) {
func SaveAfterAssociations(scope *Scope) {
for _, field := range scope.Fields() {
if scope.ValidField(field) && !field.IsBlank && !field.IsIgnored {
if scope.changeableField(field) && !field.IsBlank && !field.IsIgnored {
if relationship := field.Relationship; relationship != nil &&
(relationship.Kind == "has_one" || relationship.Kind == "has_many" || relationship.Kind == "many_to_many") {
value := field.Field

View File

@ -46,11 +46,18 @@ func Update(scope *Scope) {
sqls = append(sqls, fmt.Sprintf("%v = %v", scope.Quote(key), scope.AddToVars(value)))
}
} else {
for _, field := range scope.Fields() {
if !field.IsPrimaryKey && field.IsNormal {
fields := scope.Fields()
for _, field := range fields {
if scope.changeableField(field) && !field.IsPrimaryKey && field.IsNormal {
if !field.IsBlank || !field.HasDefaultValue {
sqls = append(sqls, fmt.Sprintf("%v = %v", scope.Quote(field.DBName), scope.AddToVars(field.Field.Interface())))
}
} else if relationship := field.Relationship; relationship != nil && relationship.Kind == "belongs_to" {
if relationField := fields[relationship.ForeignDBName]; !scope.changeableField(relationField) {
if !relationField.IsBlank {
sqls = append(sqls, fmt.Sprintf("%v = %v", scope.Quote(relationField.DBName), scope.AddToVars(relationField.Field.Interface())))
}
}
}
}
}

View File

@ -124,7 +124,7 @@ func TestAnonymousField(t *testing.T) {
func TestSelectWithCreate(t *testing.T) {
user := getPreparedUser("select_user", "select_with_create")
DB.Select("Name", "BillingAddress", "CreditCard", "Company", "Emails").Create(&user)
DB.Select("Name", "BillingAddress", "CreditCard", "Company", "Emails").Create(user)
var queryuser User
DB.Preload("BillingAddress").Preload("ShippingAddress").
@ -142,7 +142,7 @@ func TestSelectWithCreate(t *testing.T) {
func TestOmitWithCreate(t *testing.T) {
user := getPreparedUser("omit_user", "omit_with_create")
DB.Omit("Name", "BillingAddress", "CreditCard", "Company", "Emails").Create(&user)
DB.Omit("Name", "BillingAddress", "CreditCard", "Company", "Emails").Create(user)
var queryuser User
DB.Preload("BillingAddress").Preload("ShippingAddress").

View File

@ -351,7 +351,7 @@ func (scope *Scope) OmitAttrs() []string {
return scope.Search.omits
}
func (scope *Scope) ValidField(field *Field) bool {
func (scope *Scope) changeableField(field *Field) bool {
selectAttrs := scope.SelectAttrs()
omitAttrs := scope.OmitAttrs()

View File

@ -206,3 +206,71 @@ func TestUpdateColumn(t *testing.T) {
t.Errorf("UpdateColumn with expression should not update UpdatedAt")
}
}
func TestSelectWithUpdate(t *testing.T) {
user := getPreparedUser("select_user", "select_with_update")
DB.Create(user)
var reloadUser User
DB.First(&reloadUser, user.Id)
reloadUser.Name = "new_name"
reloadUser.Age = 50
reloadUser.BillingAddress = Address{Address1: "New Billing Address"}
reloadUser.ShippingAddress = Address{Address1: "New ShippingAddress Address"}
reloadUser.CreditCard = CreditCard{Number: "987654321"}
reloadUser.Emails = []Email{
{Email: "new_user_1@example1.com"}, {Email: "new_user_2@example2.com"}, {Email: "new_user_3@example2.com"},
}
reloadUser.Company = Company{Name: "new company"}
DB.Select("Name", "BillingAddress", "CreditCard", "Company", "Emails").Save(&reloadUser)
var queryUser User
DB.Preload("BillingAddress").Preload("ShippingAddress").
Preload("CreditCard").Preload("Emails").Preload("Company").First(&queryUser, user.Id)
if queryUser.Name == user.Name || queryUser.Age != user.Age {
t.Errorf("Should only update users with name column")
}
if queryUser.BillingAddressID.Int64 == user.BillingAddressID.Int64 ||
queryUser.ShippingAddressId != user.ShippingAddressId ||
queryUser.CreditCard.ID == user.CreditCard.ID ||
len(queryUser.Emails) == len(user.Emails) || queryUser.Company.Id == user.Company.Id {
t.Errorf("Should only update selected relationships")
}
}
func TestOmitWithUpdate(t *testing.T) {
user := getPreparedUser("omit_user", "omit_with_update")
DB.Create(user)
var reloadUser User
DB.First(&reloadUser, user.Id)
reloadUser.Name = "new_name"
reloadUser.Age = 50
reloadUser.BillingAddress = Address{Address1: "New Billing Address"}
reloadUser.ShippingAddress = Address{Address1: "New ShippingAddress Address"}
reloadUser.CreditCard = CreditCard{Number: "987654321"}
reloadUser.Emails = []Email{
{Email: "new_user_1@example1.com"}, {Email: "new_user_2@example2.com"}, {Email: "new_user_3@example2.com"},
}
reloadUser.Company = Company{Name: "new company"}
DB.Omit("Name", "BillingAddress", "CreditCard", "Company", "Emails").Save(&reloadUser)
var queryUser User
DB.Preload("BillingAddress").Preload("ShippingAddress").
Preload("CreditCard").Preload("Emails").Preload("Company").First(&queryUser, user.Id)
if queryUser.Name != user.Name || queryUser.Age == user.Age {
t.Errorf("Should only update users with name column")
}
if queryUser.BillingAddressID.Int64 != user.BillingAddressID.Int64 ||
queryUser.ShippingAddressId == user.ShippingAddressId ||
queryUser.CreditCard.ID != user.CreditCard.ID ||
len(queryUser.Emails) != len(user.Emails) || queryUser.Company.Id != user.Company.Id {
t.Errorf("Should only update selected relationships")
}
}