Make association Count works

This commit is contained in:
Jinzhu 2014-07-30 21:43:53 +08:00
parent 6c4b635176
commit db3da2c636
2 changed files with 29 additions and 21 deletions

View File

@ -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
} }

View File

@ -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")
} }