Test Polymorphic HasOne Association

This commit is contained in:
Jinzhu 2020-05-24 23:28:06 +08:00
parent 68a7a8207a
commit 6a0ef985ff
2 changed files with 81 additions and 7 deletions

View File

@ -179,9 +179,9 @@ func (association *Association) Replace(values ...interface{}) error {
func (association *Association) Delete(values ...interface{}) error { func (association *Association) Delete(values ...interface{}) error {
if association.Error == nil { if association.Error == nil {
var ( var (
tx = association.DB reflectValue = association.DB.Statement.ReflectValue
rel = association.Relationship rel = association.Relationship
reflectValue = tx.Statement.ReflectValue tx = association.DB
relFields []*schema.Field relFields []*schema.Field
foreignKeyFields []*schema.Field foreignKeyFields []*schema.Field
foreignKeys []string foreignKeys []string
@ -201,14 +201,12 @@ func (association *Association) Delete(values ...interface{}) error {
foreignKeys = append(foreignKeys, ref.ForeignKey.DBName) foreignKeys = append(foreignKeys, ref.ForeignKey.DBName)
updateAttrs[ref.ForeignKey.DBName] = nil updateAttrs[ref.ForeignKey.DBName] = nil
} }
} else {
tx.Where(clause.Eq{Column: ref.ForeignKey.DBName, Value: ref.PrimaryKey})
} }
} }
relValuesMap, relQueryValues := schema.GetIdentityFieldValuesMapFromValues(values, relFields) relValuesMap, relQueryValues := schema.GetIdentityFieldValuesMapFromValues(values, relFields)
column, values := schema.ToQueryValues(foreignKeys, relQueryValues) column, values := schema.ToQueryValues(foreignKeys, relQueryValues)
tx.Where(clause.IN{Column: column, Values: values}) tx = tx.Session(&Session{}).Where(clause.IN{Column: column, Values: values})
switch rel.Type { switch rel.Type {
case schema.HasOne, schema.HasMany: case schema.HasOne, schema.HasMany:
@ -407,7 +405,7 @@ func (association *Association) saveAssociation(clear bool, values ...interface{
if clear && len(values) == 0 { if clear && len(values) == 0 {
association.Relationship.Field.Set(reflectValue, reflect.New(association.Relationship.Field.IndirectFieldType).Interface()) association.Relationship.Field.Set(reflectValue, reflect.New(association.Relationship.Field.IndirectFieldType).Interface())
for _, ref := range association.Relationship.References { for _, ref := range association.Relationship.References {
if !ref.OwnPrimaryKey { if !ref.OwnPrimaryKey && ref.PrimaryValue == "" {
ref.ForeignKey.Set(reflectValue, reflect.Zero(ref.ForeignKey.FieldType).Interface()) ref.ForeignKey.Set(reflectValue, reflect.Zero(ref.ForeignKey.FieldType).Interface())
} }
} }

View File

@ -285,7 +285,7 @@ func TestHasOneAssociation(t *testing.T) {
AssertAssociationCount(t, user2, "Account", 1, "AfterReplace") AssertAssociationCount(t, user2, "Account", 1, "AfterReplace")
// Delete // Delete
if err := DB.Model(&user2).Association("Account").Delete(&Company{}); err != nil { if err := DB.Model(&user2).Association("Account").Delete(&Account{}); err != nil {
t.Fatalf("Error happened when delete account, got %v", err) t.Fatalf("Error happened when delete account, got %v", err)
} }
AssertAssociationCount(t, user2, "Account", 1, "after delete non-existing data") AssertAssociationCount(t, user2, "Account", 1, "after delete non-existing data")
@ -309,3 +309,79 @@ func TestHasOneAssociation(t *testing.T) {
AssertAssociationCount(t, user2, "Account", 0, "after clear") AssertAssociationCount(t, user2, "Account", 0, "after clear")
} }
func TestPolymorphicHasOneAssociation(t *testing.T) {
var pet = Pet{Name: "hasone", Toy: Toy{Name: "toy-has-one"}}
if err := DB.Create(&pet).Error; err != nil {
t.Fatalf("errors happened when create: %v", err)
}
CheckPet(t, pet, pet)
// Find
var pet2 Pet
DB.Find(&pet2, "id = ?", pet.ID)
DB.Model(&pet2).Association("Toy").Find(&pet2.Toy)
CheckPet(t, pet2, pet)
// Count
AssertAssociationCount(t, pet, "Toy", 1, "")
// Append
var toy = Toy{Name: "toy-has-one-append"}
if err := DB.Model(&pet2).Association("Toy").Append(&toy); err != nil {
t.Fatalf("Error happened when append toy, got %v", err)
}
if toy.ID == 0 {
t.Fatalf("Toy's ID should be created")
}
pet.Toy = toy
CheckPet(t, pet2, pet)
AssertAssociationCount(t, pet, "Toy", 1, "AfterAppend")
// Replace
var toy2 = Toy{Name: "toy-has-one-replace"}
if err := DB.Model(&pet2).Association("Toy").Replace(&toy2); err != nil {
t.Fatalf("Error happened when append Toy, got %v", err)
}
if toy2.ID == 0 {
t.Fatalf("toy2's ID should be created")
}
pet.Toy = toy2
CheckPet(t, pet2, pet)
AssertAssociationCount(t, pet2, "Toy", 1, "AfterReplace")
// Delete
if err := DB.Model(&pet2).Association("Toy").Delete(&Toy{}); err != nil {
t.Fatalf("Error happened when delete toy, got %v", err)
}
AssertAssociationCount(t, pet2, "Toy", 1, "after delete non-existing data")
if err := DB.Model(&pet2).Association("Toy").Delete(&toy2); err != nil {
t.Fatalf("Error happened when delete Toy, got %v", err)
}
AssertAssociationCount(t, pet2, "Toy", 0, "after delete")
// Prepare Data for Clear
if err := DB.Model(&pet2).Association("Toy").Append(&toy); err != nil {
t.Fatalf("Error happened when append Toy, got %v", err)
}
AssertAssociationCount(t, pet2, "Toy", 1, "after prepare data")
// Clear
if err := DB.Model(&pet2).Association("Toy").Clear(); err != nil {
t.Errorf("Error happened when clear Toy, got %v", err)
}
AssertAssociationCount(t, pet2, "Toy", 0, "after clear")
}