work only on has association
This commit is contained in:
parent
7338637d88
commit
1bfa31fa7f
@ -85,6 +85,7 @@ func (association *Association) Replace(values ...interface{}) error {
|
||||
switch rel.Type {
|
||||
case schema.BelongsTo:
|
||||
if len(values) == 0 {
|
||||
updateMap := map[string]interface{}{}
|
||||
switch reflectValue.Kind() {
|
||||
case reflect.Slice, reflect.Array:
|
||||
for i := 0; i < reflectValue.Len(); i++ {
|
||||
@ -94,17 +95,11 @@ func (association *Association) Replace(values ...interface{}) error {
|
||||
association.Error = rel.Field.Set(association.DB.Statement.Context, reflectValue, reflect.Zero(rel.Field.FieldType).Interface())
|
||||
}
|
||||
|
||||
if association.Unscope {
|
||||
modelValue := reflect.New(rel.FieldSchema.ModelType).Interface()
|
||||
association.Error = association.DB.Delete(modelValue).Error
|
||||
} else {
|
||||
updateMap := map[string]interface{}{}
|
||||
for _, ref := range rel.References {
|
||||
updateMap[ref.ForeignKey.DBName] = nil
|
||||
}
|
||||
association.Error = association.DB.UpdateColumns(updateMap).Error
|
||||
}
|
||||
}
|
||||
case schema.HasOne, schema.HasMany:
|
||||
var (
|
||||
primaryFields []*schema.Field
|
||||
@ -216,11 +211,7 @@ func (association *Association) Delete(values ...interface{}) error {
|
||||
relColumn, relValues := schema.ToQueryValues(rel.Schema.Table, foreignKeys, rvs)
|
||||
conds = append(conds, clause.IN{Column: relColumn, Values: relValues})
|
||||
|
||||
if association.Unscope {
|
||||
association.Error = tx.Clauses(conds...).Delete(model).Error
|
||||
} else {
|
||||
association.Error = tx.Clauses(conds...).UpdateColumns(updateAttrs).Error
|
||||
}
|
||||
case schema.HasOne, schema.HasMany:
|
||||
model := reflect.New(rel.FieldSchema.ModelType).Interface()
|
||||
tx := association.DB.Model(model)
|
||||
|
@ -3,6 +3,7 @@ package tests_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"gorm.io/gorm"
|
||||
. "gorm.io/gorm/utils/tests"
|
||||
)
|
||||
|
||||
@ -471,3 +472,76 @@ func TestPolymorphicHasManyAssociationForSlice(t *testing.T) {
|
||||
DB.Model(&users).Association("Toys").Clear()
|
||||
AssertAssociationCount(t, users, "Toys", 0, "After Clear")
|
||||
}
|
||||
|
||||
func TestHasManyAssociationUnscoped(t *testing.T) {
|
||||
type ItemContent struct {
|
||||
gorm.Model
|
||||
ItemID uint `gorm:"not null"`
|
||||
Name string `gorm:"not null;type:varchar(50)"`
|
||||
LanguageCode string `gorm:"not null;type:varchar(2)"`
|
||||
}
|
||||
type Item struct {
|
||||
gorm.Model
|
||||
Logo string `gorm:"not null;type:varchar(50)"`
|
||||
Contents []ItemContent `gorm:"foreignKey:ItemID"`
|
||||
}
|
||||
|
||||
tx := DB.Session(&gorm.Session{})
|
||||
tx.Migrator().DropTable(&ItemContent{}, &Item{})
|
||||
tx.AutoMigrate(&ItemContent{}, &Item{})
|
||||
|
||||
item := Item{
|
||||
Logo: "logo",
|
||||
Contents: []ItemContent{
|
||||
{Name: "name", LanguageCode: "en"},
|
||||
{Name: "ar name", LanguageCode: "ar"},
|
||||
},
|
||||
}
|
||||
if err := tx.Create(&item).Error; err != nil {
|
||||
t.Fatalf("failed to create items, got error: %v", err)
|
||||
}
|
||||
|
||||
// test Replace
|
||||
if err := tx.Model(&item).Association("Contents").Unscoped().Replace([]ItemContent{
|
||||
{Name: "updated name", LanguageCode: "en"},
|
||||
{Name: "ar updated name", LanguageCode: "ar"},
|
||||
{Name: "le nom", LanguageCode: "fr"},
|
||||
}); err != nil {
|
||||
t.Errorf("failed to replace item content, got error: %v", err)
|
||||
}
|
||||
|
||||
if count := tx.Model(&item).Association("Contents").Count(); count != 3 {
|
||||
t.Errorf("expected %d contents, got %d", 3, count)
|
||||
}
|
||||
|
||||
var contents []ItemContent
|
||||
if err := tx.Find(&contents).Error; err != nil {
|
||||
t.Errorf("failed to find contents, got error: %v", err)
|
||||
}
|
||||
if len(contents) != 3 {
|
||||
t.Errorf("expected %d contents, got %d", 3, len(contents))
|
||||
}
|
||||
|
||||
// test delete
|
||||
if err := tx.Model(&item).Association("Contents").Unscoped().Delete(&contents[0]); err != nil {
|
||||
t.Errorf("failed to delete Contents, got error: %v", err)
|
||||
}
|
||||
if count := tx.Model(&item).Association("Contents").Count(); count != 2 {
|
||||
t.Errorf("expected %d contents, got %d", 2, count)
|
||||
}
|
||||
|
||||
// test clear
|
||||
if err := tx.Model(&item).Association("Contents").Unscoped().Clear(); err != nil {
|
||||
t.Errorf("failed to clear contents association, got error: %v", err)
|
||||
}
|
||||
if count := tx.Model(&item).Association("Contents").Count(); count != 0 {
|
||||
t.Errorf("expected %d contents, got %d", 0, count)
|
||||
}
|
||||
|
||||
if err := tx.Find(&contents).Error; err != nil {
|
||||
t.Errorf("failed to find contents, got error: %v", err)
|
||||
}
|
||||
if len(contents) != 0 {
|
||||
t.Errorf("expected %d contents, got %d", 0, len(contents))
|
||||
}
|
||||
}
|
||||
|
@ -394,76 +394,3 @@ func TestAssociationEmptyPrimaryKey(t *testing.T) {
|
||||
|
||||
AssertEqual(t, result, user)
|
||||
}
|
||||
|
||||
func TestAssociationUnscoped(t *testing.T) {
|
||||
type ItemContent struct {
|
||||
gorm.Model
|
||||
ItemID uint `gorm:"not null"`
|
||||
Name string `gorm:"not null;type:varchar(50)"`
|
||||
LanguageCode string `gorm:"not null;type:varchar(2)"`
|
||||
}
|
||||
type Item struct {
|
||||
gorm.Model
|
||||
Logo string `gorm:"not null;type:varchar(50)"`
|
||||
Contents []ItemContent `gorm:"foreignKey:ItemID"`
|
||||
}
|
||||
|
||||
tx := DB.Session(&gorm.Session{})
|
||||
tx.Migrator().DropTable(&ItemContent{}, &Item{})
|
||||
tx.AutoMigrate(&ItemContent{}, &Item{})
|
||||
|
||||
item := Item{
|
||||
Logo: "logo",
|
||||
Contents: []ItemContent{
|
||||
{Name: "name", LanguageCode: "en"},
|
||||
{Name: "ar name", LanguageCode: "ar"},
|
||||
},
|
||||
}
|
||||
if err := tx.Create(&item).Error; err != nil {
|
||||
t.Fatalf("failed to create items, got error: %v", err)
|
||||
}
|
||||
|
||||
// test Replace
|
||||
if err := tx.Model(&item).Association("Contents").Unscoped().Replace([]ItemContent{
|
||||
{Name: "updated name", LanguageCode: "en"},
|
||||
{Name: "ar updated name", LanguageCode: "ar"},
|
||||
{Name: "le nom", LanguageCode: "fr"},
|
||||
}); err != nil {
|
||||
t.Errorf("failed to replace item content, got error: %v", err)
|
||||
}
|
||||
|
||||
if count := tx.Model(&item).Association("Contents").Count(); count != 3 {
|
||||
t.Errorf("expected %d contents, got %d", 3, count)
|
||||
}
|
||||
|
||||
var contents []ItemContent
|
||||
if err := tx.Find(&contents).Error; err != nil {
|
||||
t.Errorf("failed to find contents, got error: %v", err)
|
||||
}
|
||||
if len(contents) != 3 {
|
||||
t.Errorf("expected 3 contents, got %d", len(contents))
|
||||
}
|
||||
|
||||
// test delete
|
||||
if err := tx.Model(&item).Association("Contents").Unscoped().Delete(&contents[0]); err != nil {
|
||||
t.Errorf("failed to delete Contents, got error: %v", err)
|
||||
}
|
||||
if count := tx.Model(&item).Association("Contents").Count(); count != 2 {
|
||||
t.Errorf("expected %d contents, got %d", 2, count)
|
||||
}
|
||||
|
||||
// test clear
|
||||
if err := tx.Model(&item).Association("Contents").Unscoped().Clear(); err != nil {
|
||||
t.Errorf("failed to clear contents association, got error: %v", err)
|
||||
}
|
||||
if count := tx.Model(&item).Association("Contents").Count(); count != 0 {
|
||||
t.Errorf("expected %d contents, got %d", 0, count)
|
||||
}
|
||||
|
||||
if err := tx.Find(&contents).Error; err != nil {
|
||||
t.Errorf("failed to find contents, got error: %v", err)
|
||||
}
|
||||
if len(contents) != 0 {
|
||||
t.Errorf("expected %d contents, got %d", 0, len(contents))
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user