mirror of https://github.com/go-gorm/gorm.git
Fix Association Count with Soft Delete
This commit is contained in:
parent
801a271d07
commit
43e9035dad
|
@ -293,6 +293,34 @@ func TestHasOne(t *testing.T) {
|
|||
if DB.Model(&user).Association("CreditCard").Count() != 0 {
|
||||
t.Errorf("User's credit card count should be 0 after Clear")
|
||||
}
|
||||
|
||||
// Check Association mode with soft delete
|
||||
var creditcard6 = CreditCard{
|
||||
Number: "411111111116",
|
||||
}
|
||||
DB.Model(&user).Association("CreditCard").Append(&creditcard6)
|
||||
|
||||
if count := DB.Model(&user).Association("CreditCard").Count(); count != 1 {
|
||||
t.Errorf("User's credit card count should be 1 after Append, but got %v", count)
|
||||
}
|
||||
|
||||
DB.Delete(&creditcard6)
|
||||
|
||||
if count := DB.Model(&user).Association("CreditCard").Count(); count != 0 {
|
||||
t.Errorf("User's credit card count should be 0 after credit card deleted, but got %v", count)
|
||||
}
|
||||
|
||||
if err := DB.Model(&user).Association("CreditCard").Find(&CreditCard{}).Error; err == nil {
|
||||
t.Errorf("User's creditcard is not findable after Delete")
|
||||
}
|
||||
|
||||
if count := DB.Unscoped().Model(&user).Association("CreditCard").Count(); count != 1 {
|
||||
t.Errorf("User's credit card count should be 1 when query with Unscoped, but got %v", count)
|
||||
}
|
||||
|
||||
if err := DB.Unscoped().Model(&user).Association("CreditCard").Find(&CreditCard{}).Error; err != nil {
|
||||
t.Errorf("User's creditcard should be findable when query with Unscoped, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHasMany(t *testing.T) {
|
||||
|
@ -402,6 +430,36 @@ func TestHasMany(t *testing.T) {
|
|||
if len(comments51) != 0 {
|
||||
t.Errorf("Clear has many relations")
|
||||
}
|
||||
|
||||
// Check Association mode with soft delete
|
||||
var comment6 = Comment{
|
||||
Content: "comment 6",
|
||||
}
|
||||
DB.Model(&post).Association("Comments").Append(&comment6)
|
||||
|
||||
if count := DB.Model(&post).Association("Comments").Count(); count != 1 {
|
||||
t.Errorf("post's comments count should be 1 after Append, but got %v", count)
|
||||
}
|
||||
|
||||
DB.Delete(&comment6)
|
||||
|
||||
if count := DB.Model(&post).Association("Comments").Count(); count != 0 {
|
||||
t.Errorf("post's comments count should be 0 after comment been deleted, but got %v", count)
|
||||
}
|
||||
|
||||
var comments6 []Comment
|
||||
if DB.Model(&post).Association("Comments").Find(&comments6); len(comments6) != 0 {
|
||||
t.Errorf("post's comments count should be 0 when find with Find, but got %v", len(comments6))
|
||||
}
|
||||
|
||||
if count := DB.Unscoped().Model(&post).Association("Comments").Count(); count != 1 {
|
||||
t.Errorf("post's comments count should be 1 when query with Unscoped, but got %v", count)
|
||||
}
|
||||
|
||||
var comments61 []Comment
|
||||
if DB.Unscoped().Model(&post).Association("Comments").Find(&comments61); len(comments61) != 1 {
|
||||
t.Errorf("post's comments count should be 1 when query with Unscoped, but got %v", len(comments61))
|
||||
}
|
||||
}
|
||||
|
||||
func TestManyToMany(t *testing.T) {
|
||||
|
@ -500,6 +558,36 @@ func TestManyToMany(t *testing.T) {
|
|||
if len(user.Languages) != 0 || DB.Model(&user).Association("Languages").Count() != 0 {
|
||||
t.Errorf("Relations should be cleared")
|
||||
}
|
||||
|
||||
// Check Association mode with soft delete
|
||||
var language6 = Language{
|
||||
Name: "language 6",
|
||||
}
|
||||
DB.Model(&user).Association("Languages").Append(&language6)
|
||||
|
||||
if count := DB.Model(&user).Association("Languages").Count(); count != 1 {
|
||||
t.Errorf("user's languages count should be 1 after Append, but got %v", count)
|
||||
}
|
||||
|
||||
DB.Delete(&language6)
|
||||
|
||||
if count := DB.Model(&user).Association("Languages").Count(); count != 0 {
|
||||
t.Errorf("user's languages count should be 0 after language been deleted, but got %v", count)
|
||||
}
|
||||
|
||||
var languages6 []Language
|
||||
if DB.Model(&user).Association("Languages").Find(&languages6); len(languages6) != 0 {
|
||||
t.Errorf("user's languages count should be 0 when find with Find, but got %v", len(languages6))
|
||||
}
|
||||
|
||||
if count := DB.Unscoped().Model(&user).Association("Languages").Count(); count != 1 {
|
||||
t.Errorf("user's languages count should be 1 when query with Unscoped, but got %v", count)
|
||||
}
|
||||
|
||||
var languages61 []Language
|
||||
if DB.Unscoped().Model(&user).Association("Languages").Find(&languages61); len(languages61) != 1 {
|
||||
t.Errorf("user's languages count should be 1 when query with Unscoped, but got %v", len(languages61))
|
||||
}
|
||||
}
|
||||
|
||||
func TestRelated(t *testing.T) {
|
||||
|
|
|
@ -8,7 +8,7 @@ func BeforeDelete(scope *Scope) {
|
|||
|
||||
func Delete(scope *Scope) {
|
||||
if !scope.HasError() {
|
||||
if !scope.Search.Unscoped && scope.HasColumn("DeletedAt") {
|
||||
if !scope.db.unscoped && scope.HasColumn("DeletedAt") {
|
||||
scope.Raw(
|
||||
fmt.Sprintf("UPDATE %v SET deleted_at=%v %v",
|
||||
scope.QuotedTableName(),
|
||||
|
|
7
main.go
7
main.go
|
@ -28,6 +28,7 @@ type DB struct {
|
|||
parent *DB
|
||||
search *search
|
||||
logMode int
|
||||
unscoped bool
|
||||
logger logger
|
||||
dialect Dialect
|
||||
singularTable bool
|
||||
|
@ -186,7 +187,9 @@ func (s *DB) Scopes(funcs ...func(*DB) *DB) *DB {
|
|||
}
|
||||
|
||||
func (s *DB) Unscoped() *DB {
|
||||
return s.clone().search.unscoped().db
|
||||
clone := s.clone()
|
||||
clone.unscoped = true
|
||||
return clone
|
||||
}
|
||||
|
||||
func (s *DB) Attrs(attrs ...interface{}) *DB {
|
||||
|
@ -434,7 +437,7 @@ func (s *DB) DropColumn(column string) *DB {
|
|||
}
|
||||
|
||||
func (s *DB) AddIndex(indexName string, column ...string) *DB {
|
||||
scope := s.clone().NewScope(s.Value)
|
||||
scope := s.Unscoped().NewScope(s.Value)
|
||||
scope.addIndex(false, indexName, column...)
|
||||
return scope.db
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ package gorm
|
|||
import "time"
|
||||
|
||||
func (s *DB) clone() *DB {
|
||||
db := DB{db: s.db, parent: s.parent, logger: s.logger, logMode: s.logMode, values: map[string]interface{}{}, Value: s.Value, Error: s.Error}
|
||||
db := DB{db: s.db, parent: s.parent, logger: s.logger, logMode: s.logMode, unscoped: s.unscoped, values: map[string]interface{}{}, Value: s.Value, Error: s.Error}
|
||||
|
||||
for key, value := range s.values {
|
||||
db.values[key] = value
|
||||
|
|
|
@ -161,7 +161,7 @@ func (scope *Scope) buildSelectQuery(clause map[string]interface{}) (str string)
|
|||
func (scope *Scope) whereSql() (sql string) {
|
||||
var primaryConditions, andConditions, orConditions []string
|
||||
|
||||
if !scope.Search.Unscoped && scope.Fields()["deleted_at"] != nil {
|
||||
if !scope.db.unscoped && scope.Fields()["deleted_at"] != nil {
|
||||
sql := fmt.Sprintf("(%v.deleted_at IS NULL OR %v.deleted_at <= '0001-01-02')", scope.QuotedTableName(), scope.QuotedTableName())
|
||||
primaryConditions = append(primaryConditions, sql)
|
||||
}
|
||||
|
@ -601,9 +601,7 @@ func (scope *Scope) addIndex(unique bool, indexName string, column ...string) {
|
|||
sqlCreate = "CREATE UNIQUE INDEX"
|
||||
}
|
||||
|
||||
scope.Search.Unscoped = true
|
||||
scope.Raw(fmt.Sprintf("%s %v ON %v(%v) %v", sqlCreate, indexName, scope.QuotedTableName(), strings.Join(columns, ", "), scope.whereSql())).Exec()
|
||||
scope.Search.Unscoped = false
|
||||
}
|
||||
|
||||
func (scope *Scope) addForeignKey(field string, dest string, onDelete string, onUpdate string) {
|
||||
|
@ -659,11 +657,11 @@ func (scope *Scope) autoIndex() *Scope {
|
|||
}
|
||||
|
||||
for name, columns := range indexes {
|
||||
scope.addIndex(false, name, columns...)
|
||||
scope.NewDB().Model(scope.Value).AddIndex(name, columns...)
|
||||
}
|
||||
|
||||
for name, columns := range uniqueIndexes {
|
||||
scope.addIndex(true, name, columns...)
|
||||
scope.NewDB().Model(scope.Value).AddUniqueIndex(name, columns...)
|
||||
}
|
||||
|
||||
return scope
|
||||
|
|
|
@ -20,7 +20,6 @@ type search struct {
|
|||
group string
|
||||
tableName string
|
||||
raw bool
|
||||
Unscoped bool
|
||||
countingQuery bool
|
||||
}
|
||||
|
||||
|
@ -124,11 +123,6 @@ func (s *search) Raw(b bool) *search {
|
|||
return s
|
||||
}
|
||||
|
||||
func (s *search) unscoped() *search {
|
||||
s.Unscoped = true
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *search) Table(name string) *search {
|
||||
s.tableName = name
|
||||
return s
|
||||
|
|
|
@ -66,7 +66,7 @@ type Address struct {
|
|||
}
|
||||
|
||||
type Language struct {
|
||||
Id int
|
||||
gorm.Model
|
||||
Name string
|
||||
Users []User `gorm:"many2many:user_languages;"`
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue