Fix tests

This commit is contained in:
Jinzhu 2015-03-19 18:23:54 +08:00
parent 36efd0a561
commit 44b106c8e2
6 changed files with 49 additions and 42 deletions

View File

@ -163,9 +163,7 @@ func (association *Association) Count() int {
newScope := scope.New(association.Field.Field.Interface()) newScope := scope.New(association.Field.Field.Interface())
if relationship.Kind == "many_to_many" { if relationship.Kind == "many_to_many" {
query := scope.DB().Select("COUNT(DISTINCT ?)", relationship.AssociationForeignDBName). relationship.JoinTableHandler.JoinWith(scope.NewDB(), association.Scope.Value).Table(newScope.TableName()).Count(&count)
Where(relationship.ForeignDBName+" = ?", association.PrimaryKey)
relationship.JoinTableHandler.JoinWith(query, association.Scope.Value).Count(&count)
} else if relationship.Kind == "has_many" || relationship.Kind == "has_one" { } else if relationship.Kind == "has_many" || relationship.Kind == "has_one" {
whereSql := fmt.Sprintf("%v.%v = ?", newScope.QuotedTableName(), newScope.Quote(relationship.ForeignDBName)) whereSql := fmt.Sprintf("%v.%v = ?", newScope.QuotedTableName(), newScope.Quote(relationship.ForeignDBName))
countScope := scope.DB().Table(newScope.TableName()).Where(whereSql, association.PrimaryKey) countScope := scope.DB().Table(newScope.TableName()).Where(whereSql, association.PrimaryKey)

View File

@ -143,7 +143,7 @@ func TestManyToMany(t *testing.T) {
// Query // Query
var newLanguages []Language var newLanguages []Language
DB.Debug().Model(&user).Related(&newLanguages, "Languages") DB.Model(&user).Related(&newLanguages, "Languages")
if len(newLanguages) != len([]string{"ZH", "EN"}) { if len(newLanguages) != len([]string{"ZH", "EN"}) {
t.Errorf("Query many to many relations") t.Errorf("Query many to many relations")
} }

View File

@ -18,28 +18,6 @@ type JoinTableForeignKey struct {
AssociationDBName string AssociationDBName string
} }
func updateJoinTableHandler(relationship *Relationship) {
handler := relationship.JoinTableHandler.(*JoinTableHandler)
destinationScope := &Scope{Value: reflect.New(handler.Destination.ModelType).Interface()}
for _, primaryField := range destinationScope.GetModelStruct().PrimaryFields {
db := relationship.ForeignDBName
handler.Destination.ForeignKeys = append(handler.Destination.ForeignKeys, JoinTableForeignKey{
DBName: db,
AssociationDBName: primaryField.DBName,
})
}
sourceScope := &Scope{Value: reflect.New(handler.Source.ModelType).Interface()}
for _, primaryField := range sourceScope.GetModelStruct().PrimaryFields {
db := relationship.AssociationForeignDBName
handler.Source.ForeignKeys = append(handler.Source.ForeignKeys, JoinTableForeignKey{
DBName: db,
AssociationDBName: primaryField.DBName,
})
}
}
type JoinTableSource struct { type JoinTableSource struct {
ModelType reflect.Type ModelType reflect.Type
ForeignKeys []JoinTableForeignKey ForeignKeys []JoinTableForeignKey
@ -51,6 +29,28 @@ type JoinTableHandler struct {
Destination JoinTableSource `sql:"-"` Destination JoinTableSource `sql:"-"`
} }
func updateJoinTableHandler(relationship *Relationship) {
handler := relationship.JoinTableHandler.(*JoinTableHandler)
destinationScope := &Scope{Value: reflect.New(handler.Destination.ModelType).Interface()}
for _, primaryField := range destinationScope.GetModelStruct().PrimaryFields {
db := relationship.AssociationForeignDBName
handler.Destination.ForeignKeys = append(handler.Destination.ForeignKeys, JoinTableForeignKey{
DBName: db,
AssociationDBName: primaryField.DBName,
})
}
sourceScope := &Scope{Value: reflect.New(handler.Source.ModelType).Interface()}
for _, primaryField := range sourceScope.GetModelStruct().PrimaryFields {
db := relationship.ForeignDBName
handler.Source.ForeignKeys = append(handler.Source.ForeignKeys, JoinTableForeignKey{
DBName: db,
AssociationDBName: primaryField.DBName,
})
}
}
func (s JoinTableHandler) Table(*DB) string { func (s JoinTableHandler) Table(*DB) string {
return s.TableName return s.TableName
} }
@ -88,7 +88,7 @@ func (s JoinTableHandler) Add(db *DB, source1 interface{}, source2 interface{})
values = append(values, value) values = append(values, value)
} }
for _, value := range searchMap { for _, value := range values {
values = append(values, value) values = append(values, value)
} }

View File

@ -15,29 +15,32 @@ type Person struct {
} }
type PersonAddress struct { type PersonAddress struct {
gorm.JoinTableHandler
PersonID int PersonID int
AddressID int AddressID int
DeletedAt time.Time DeletedAt time.Time
CreatedAt time.Time CreatedAt time.Time
} }
func (*PersonAddress) Add(db *gorm.DB, relationship *gorm.Relationship, foreignValue interface{}, associationValue interface{}) error { func (*PersonAddress) Table(db *gorm.DB) string {
return "person_addresses"
}
func (*PersonAddress) Add(db *gorm.DB, foreignValue interface{}, associationValue interface{}) error {
return db.Where(map[string]interface{}{ return db.Where(map[string]interface{}{
relationship.ForeignDBName: foreignValue, "person_id": db.NewScope(foreignValue).PrimaryKeyValue(),
relationship.AssociationForeignDBName: associationValue, "address_id": db.NewScope(associationValue).PrimaryKeyValue(),
}).Assign(map[string]interface{}{ }).Assign(map[string]interface{}{
relationship.ForeignFieldName: foreignValue, "person_id": foreignValue,
relationship.AssociationForeignFieldName: associationValue, "address_id": associationValue,
"DeletedAt": gorm.Expr("NULL"), "DeletedAt": gorm.Expr("NULL"),
}).FirstOrCreate(&PersonAddress{}).Error }).FirstOrCreate(&PersonAddress{}).Error
} }
func (*PersonAddress) Delete(db *gorm.DB, relationship *gorm.Relationship) error { func (*PersonAddress) Delete(db *gorm.DB, sources ...interface{}) error {
return db.Delete(&PersonAddress{}).Error return db.Delete(&PersonAddress{}).Error
} }
func (pa *PersonAddress) Scope(db *gorm.DB, relationship *gorm.Relationship) *gorm.DB { func (pa *PersonAddress) JoinWith(db *gorm.DB, source interface{}) *gorm.DB {
table := pa.Table(db) table := pa.Table(db)
return db.Table(table).Where(fmt.Sprintf("%v.deleted_at IS NULL OR %v.deleted_at <= '0001-01-02'", table, table)) return db.Table(table).Where(fmt.Sprintf("%v.deleted_at IS NULL OR %v.deleted_at <= '0001-01-02'", table, table))
} }
@ -45,7 +48,7 @@ func (pa *PersonAddress) Scope(db *gorm.DB, relationship *gorm.Relationship) *go
func TestJoinTable(t *testing.T) { func TestJoinTable(t *testing.T) {
DB.Exec("drop table person_addresses;") DB.Exec("drop table person_addresses;")
DB.AutoMigrate(&Person{}) DB.AutoMigrate(&Person{})
// DB.SetJoinTableHandler(&PersonAddress{}, "person_addresses") DB.SetJoinTableHandler(&Person{}, "Addresses", &PersonAddress{})
address1 := &Address{Address1: "address 1"} address1 := &Address{Address1: "address 1"}
address2 := &Address{Address1: "address 2"} address2 := &Address{Address1: "address 2"}
@ -58,7 +61,7 @@ func TestJoinTable(t *testing.T) {
t.Errorf("Should found one address") t.Errorf("Should found one address")
} }
if DB.Model(person).Association("Addresses").Count() != 1 { if DB.Debug().Model(person).Association("Addresses").Count() != 1 {
t.Errorf("Should found one address") t.Errorf("Should found one address")
} }

View File

@ -469,3 +469,12 @@ func (s *DB) Get(name string) (value interface{}, ok bool) {
value, ok = s.values[name] value, ok = s.values[name]
return return
} }
func (s *DB) SetJoinTableHandler(source interface{}, column string, handler JoinTableHandlerInterface) {
for _, field := range s.NewScope(source).GetModelStruct().StructFields {
if field.Name == column || field.DBName == column {
field.Relationship.JoinTableHandler = handler
s.Table(handler.Table(s)).AutoMigrate(handler)
}
}
}

View File

@ -403,10 +403,7 @@ func (scope *Scope) related(value interface{}, foreignKeys ...string) *Scope {
if relationship := fromField.Relationship; relationship != nil { if relationship := fromField.Relationship; relationship != nil {
if relationship.Kind == "many_to_many" { if relationship.Kind == "many_to_many" {
joinTableHandler := relationship.JoinTableHandler joinTableHandler := relationship.JoinTableHandler
quotedJoinTable := scope.Quote(joinTableHandler.Table(scope.db)) scope.Err(joinTableHandler.JoinWith(toScope.db, scope.Value).Find(value).Error)
scope.Err(joinTableHandler.JoinWith(toScope.db, scope.Value).
Where(fmt.Sprintf("%v.%v = ?", quotedJoinTable, scope.Quote(relationship.ForeignDBName)), scope.PrimaryKeyValue()).
Find(value).Error)
} else if relationship.Kind == "belongs_to" { } else if relationship.Kind == "belongs_to" {
sql := fmt.Sprintf("%v = ?", scope.Quote(toScope.PrimaryKey())) sql := fmt.Sprintf("%v = ?", scope.Quote(toScope.PrimaryKey()))
foreignKeyValue := fromFields[relationship.ForeignDBName].Field.Interface() foreignKeyValue := fromFields[relationship.ForeignDBName].Field.Interface()