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 {
|
switch rel.Type {
|
||||||
case schema.BelongsTo:
|
case schema.BelongsTo:
|
||||||
if len(values) == 0 {
|
if len(values) == 0 {
|
||||||
|
updateMap := map[string]interface{}{}
|
||||||
switch reflectValue.Kind() {
|
switch reflectValue.Kind() {
|
||||||
case reflect.Slice, reflect.Array:
|
case reflect.Slice, reflect.Array:
|
||||||
for i := 0; i < reflectValue.Len(); i++ {
|
for i := 0; i < reflectValue.Len(); i++ {
|
||||||
@ -94,16 +95,10 @@ func (association *Association) Replace(values ...interface{}) error {
|
|||||||
association.Error = rel.Field.Set(association.DB.Statement.Context, reflectValue, reflect.Zero(rel.Field.FieldType).Interface())
|
association.Error = rel.Field.Set(association.DB.Statement.Context, reflectValue, reflect.Zero(rel.Field.FieldType).Interface())
|
||||||
}
|
}
|
||||||
|
|
||||||
if association.Unscope {
|
for _, ref := range rel.References {
|
||||||
modelValue := reflect.New(rel.FieldSchema.ModelType).Interface()
|
updateMap[ref.ForeignKey.DBName] = nil
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
association.Error = association.DB.UpdateColumns(updateMap).Error
|
||||||
}
|
}
|
||||||
case schema.HasOne, schema.HasMany:
|
case schema.HasOne, schema.HasMany:
|
||||||
var (
|
var (
|
||||||
@ -216,11 +211,7 @@ func (association *Association) Delete(values ...interface{}) error {
|
|||||||
relColumn, relValues := schema.ToQueryValues(rel.Schema.Table, foreignKeys, rvs)
|
relColumn, relValues := schema.ToQueryValues(rel.Schema.Table, foreignKeys, rvs)
|
||||||
conds = append(conds, clause.IN{Column: relColumn, Values: relValues})
|
conds = append(conds, clause.IN{Column: relColumn, Values: relValues})
|
||||||
|
|
||||||
if association.Unscope {
|
association.Error = tx.Clauses(conds...).UpdateColumns(updateAttrs).Error
|
||||||
association.Error = tx.Clauses(conds...).Delete(model).Error
|
|
||||||
} else {
|
|
||||||
association.Error = tx.Clauses(conds...).UpdateColumns(updateAttrs).Error
|
|
||||||
}
|
|
||||||
case schema.HasOne, schema.HasMany:
|
case schema.HasOne, schema.HasMany:
|
||||||
model := reflect.New(rel.FieldSchema.ModelType).Interface()
|
model := reflect.New(rel.FieldSchema.ModelType).Interface()
|
||||||
tx := association.DB.Model(model)
|
tx := association.DB.Model(model)
|
||||||
|
@ -3,6 +3,7 @@ package tests_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
. "gorm.io/gorm/utils/tests"
|
. "gorm.io/gorm/utils/tests"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -471,3 +472,76 @@ func TestPolymorphicHasManyAssociationForSlice(t *testing.T) {
|
|||||||
DB.Model(&users).Association("Toys").Clear()
|
DB.Model(&users).Association("Toys").Clear()
|
||||||
AssertAssociationCount(t, users, "Toys", 0, "After 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)
|
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