forked from mirror/gorm
Make association Count works
This commit is contained in:
parent
6c4b635176
commit
db3da2c636
|
@ -87,11 +87,11 @@ func (association *Association) Delete(values ...interface{}) *Association {
|
||||||
} else {
|
} else {
|
||||||
relationship := association.Field.Relationship
|
relationship := association.Field.Relationship
|
||||||
// many to many
|
// many to many
|
||||||
if relationship.joinTable != "" {
|
if relationship.kind == "many_to_many" {
|
||||||
whereSql := fmt.Sprintf("%v.%v IN (?)", relationship.joinTable, scope.Quote(ToSnake(relationship.associationForeignKey)))
|
whereSql := fmt.Sprintf("%v.%v IN (?)", relationship.joinTable, scope.Quote(ToSnake(relationship.associationForeignKey)))
|
||||||
scope.db.Table(relationship.joinTable).Where(whereSql, primaryKeys).Delete("")
|
scope.db.Table(relationship.joinTable).Where(whereSql, primaryKeys).Delete("")
|
||||||
} else {
|
} else {
|
||||||
association.err(errors.New("only many to many support delete"))
|
association.err(errors.New("delete only support many to many"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return association
|
return association
|
||||||
|
@ -105,25 +105,36 @@ func (association *Association) Clear(value interface{}) *Association {
|
||||||
return association
|
return association
|
||||||
}
|
}
|
||||||
|
|
||||||
func (association *Association) Count() (count int) {
|
func (association *Association) Count() int {
|
||||||
|
count := -1
|
||||||
relationship := association.Field.Relationship
|
relationship := association.Field.Relationship
|
||||||
scope := association.Scope
|
scope := association.Scope
|
||||||
field := scope.IndirectValue().FieldByName(association.Column)
|
field := scope.IndirectValue().FieldByName(association.Column)
|
||||||
fieldValue := field.Interface()
|
fieldValue := field.Interface()
|
||||||
|
|
||||||
// many to many
|
|
||||||
if relationship.joinTable != "" {
|
|
||||||
newScope := scope.New(fieldValue)
|
newScope := scope.New(fieldValue)
|
||||||
|
|
||||||
|
if relationship.kind == "many_to_many" {
|
||||||
whereSql := fmt.Sprintf("%v.%v IN (SELECT %v.%v FROM %v WHERE %v.%v = ?)",
|
whereSql := fmt.Sprintf("%v.%v IN (SELECT %v.%v FROM %v WHERE %v.%v = ?)",
|
||||||
newScope.QuotedTableName(),
|
newScope.QuotedTableName(),
|
||||||
scope.Quote(newScope.PrimaryKey()),
|
scope.Quote(newScope.PrimaryKey()),
|
||||||
relationship.joinTable,
|
relationship.joinTable,
|
||||||
scope.Quote(relationship.associationForeignKey),
|
scope.Quote(ToSnake(relationship.associationForeignKey)),
|
||||||
relationship.joinTable,
|
relationship.joinTable,
|
||||||
relationship.joinTable,
|
relationship.joinTable,
|
||||||
scope.Quote(relationship.foreignKey))
|
scope.Quote(ToSnake(relationship.foreignKey)))
|
||||||
scope.db.Table(newScope.QuotedTableName()).Where(whereSql, scope.PrimaryKey()).Count(&count)
|
scope.db.Table(newScope.QuotedTableName()).Where(whereSql, association.PrimaryKey).NewScope("").count(&count)
|
||||||
|
} else if relationship.kind == "has_many" {
|
||||||
|
whereSql := fmt.Sprintf("%v.%v = ?", newScope.QuotedTableName(), newScope.Quote(ToSnake(relationship.foreignKey)))
|
||||||
|
scope.db.Table(newScope.QuotedTableName()).Where(whereSql, association.PrimaryKey).NewScope("").count(&count)
|
||||||
|
} else if relationship.kind == "has_one" {
|
||||||
|
whereSql := fmt.Sprintf("%v.%v = ?", newScope.QuotedTableName(), relationship.foreignKey)
|
||||||
|
scope.db.Table(newScope.QuotedTableName()).Where(whereSql, association.PrimaryKey).NewScope("").count(&count)
|
||||||
|
} else if relationship.kind == "belongs_to" {
|
||||||
|
if v, ok := scope.FieldByName(association.Column); ok {
|
||||||
|
whereSql := fmt.Sprintf("%v.%v = ?", newScope.QuotedTableName(), relationship.foreignKey)
|
||||||
|
scope.db.Table(newScope.QuotedTableName()).Where(whereSql, v).NewScope("").count(&count)
|
||||||
}
|
}
|
||||||
// association.Scope.related(value, association.Column)
|
}
|
||||||
return -1
|
|
||||||
|
return count
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,6 +145,10 @@ func TestManyToMany(t *testing.T) {
|
||||||
t.Errorf("Should be able to find many to many relations")
|
t.Errorf("Should be able to find many to many relations")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if db.Model(&user).Association("Languages").Count() != len([]string{"ZH", "EN"}) {
|
||||||
|
t.Errorf("Count should return correct result")
|
||||||
|
}
|
||||||
|
|
||||||
// Append
|
// Append
|
||||||
db.Model(&user).Association("Languages").Append(&Language{Name: "DE"})
|
db.Model(&user).Association("Languages").Append(&Language{Name: "DE"})
|
||||||
if db.Where("name = ?", "DE").First(&Language{}).RecordNotFound() {
|
if db.Where("name = ?", "DE").First(&Language{}).RecordNotFound() {
|
||||||
|
@ -161,9 +165,7 @@ func TestManyToMany(t *testing.T) {
|
||||||
|
|
||||||
totalLanguages := []string{"ZH", "EN", "DE", "AA", "BB", "CC", "DD", "EE"}
|
totalLanguages := []string{"ZH", "EN", "DE", "AA", "BB", "CC", "DD", "EE"}
|
||||||
|
|
||||||
newLanguages = []Language{}
|
if db.Model(&user).Association("Languages").Count() != len(totalLanguages) {
|
||||||
db.Model(&user).Related(&newLanguages, "Languages")
|
|
||||||
if len(newLanguages) != len(totalLanguages) {
|
|
||||||
t.Errorf("All appended languages should be saved")
|
t.Errorf("All appended languages should be saved")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,10 +173,7 @@ func TestManyToMany(t *testing.T) {
|
||||||
var language Language
|
var language Language
|
||||||
db.Where("name = ?", "EE").First(&language)
|
db.Where("name = ?", "EE").First(&language)
|
||||||
db.Model(&user).Association("Languages").Delete(language, &language)
|
db.Model(&user).Association("Languages").Delete(language, &language)
|
||||||
|
if db.Model(&user).Association("Languages").Count() != len(totalLanguages)-1 {
|
||||||
newLanguages = []Language{}
|
|
||||||
db.Model(&user).Related(&newLanguages, "Languages")
|
|
||||||
if len(newLanguages) != len(totalLanguages)-1 {
|
|
||||||
t.Errorf("Relations should be deleted with Delete")
|
t.Errorf("Relations should be deleted with Delete")
|
||||||
}
|
}
|
||||||
if db.Where("name = ?", "EE").First(&Language{}).RecordNotFound() {
|
if db.Where("name = ?", "EE").First(&Language{}).RecordNotFound() {
|
||||||
|
@ -184,9 +183,7 @@ func TestManyToMany(t *testing.T) {
|
||||||
languages = []Language{}
|
languages = []Language{}
|
||||||
db.Where("name IN (?)", []string{"CC", "DD"}).Find(&languages)
|
db.Where("name IN (?)", []string{"CC", "DD"}).Find(&languages)
|
||||||
db.Model(&user).Association("Languages").Delete(languages, &languages)
|
db.Model(&user).Association("Languages").Delete(languages, &languages)
|
||||||
newLanguages = []Language{}
|
if db.Model(&user).Association("Languages").Count() != len(totalLanguages)-3 {
|
||||||
db.Model(&user).Related(&newLanguages, "Languages")
|
|
||||||
if len(newLanguages) != len(totalLanguages)-3 {
|
|
||||||
t.Errorf("Relations should be deleted with Delete")
|
t.Errorf("Relations should be deleted with Delete")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue