From 22b1a93e03dd316f44ddefbbc583d49935c47398 Mon Sep 17 00:00:00 2001 From: Jinzhu Date: Sat, 28 Feb 2015 14:16:51 +0800 Subject: [PATCH] Add JoinTableHandler test --- join_table_test.go | 70 ++++++++++++++++++++++++++++++++++++++++++++++ main.go | 1 + scope_private.go | 17 ++++++----- 3 files changed, 79 insertions(+), 9 deletions(-) create mode 100644 join_table_test.go diff --git a/join_table_test.go b/join_table_test.go new file mode 100644 index 00000000..76866e39 --- /dev/null +++ b/join_table_test.go @@ -0,0 +1,70 @@ +package gorm_test + +import ( + "fmt" + "testing" + "time" + + "github.com/jinzhu/gorm" +) + +type Person struct { + Id int + Name string + Addresses []*Address `gorm:"many2many:person_addresses;"` +} + +type PersonAddress struct { + PersonID int + AddressID int + DeletedAt time.Time + CreatedAt time.Time +} + +func (*PersonAddress) Add(db *gorm.DB, relationship *gorm.Relationship, foreignValue interface{}, associationValue interface{}) error { + return db.Where(map[string]interface{}{ + relationship.ForeignDBName: foreignValue, + relationship.AssociationForeignDBName: associationValue, + }).Assign(map[string]interface{}{ + relationship.ForeignFieldName: foreignValue, + relationship.AssociationForeignFieldName: associationValue, + "DeletedAt": gorm.Expr("NULL"), + }).FirstOrCreate(&PersonAddress{}).Error +} + +func (*PersonAddress) Delete(db *gorm.DB, relationship *gorm.Relationship) error { + return db.Delete(&PersonAddress{}).Error +} + +func (*PersonAddress) Scope(db *gorm.DB, relationship *gorm.Relationship) *gorm.DB { + return db.Where(fmt.Sprintf("%v.deleted_at IS NULL OR %v.deleted_at <= '0001-01-02'", relationship.JoinTable, relationship.JoinTable)) +} + +func TestJoinTable(t *testing.T) { + DB.Exec("drop table person_addresses;") + DB.AutoMigrate(&Person{}) + DB.SetJoinTableHandler(&PersonAddress{}, "person_addresses") + + address1 := &Address{Address1: "address 1"} + address2 := &Address{Address1: "address 2"} + person := &Person{Name: "person", Addresses: []*Address{address1, address2}} + DB.Save(person) + + DB.Model(person).Association("Addresses").Delete(address1) + + if DB.Find(&[]PersonAddress{}, "person_id = ?", person.Id).RowsAffected != 1 { + t.Errorf("Should found one address") + } + + if DB.Model(person).Association("Addresses").Count() != 1 { + t.Errorf("Should found one address") + } + + if DB.Unscoped().Find(&[]PersonAddress{}, "person_id = ?", person.Id).RowsAffected != 2 { + t.Errorf("Found two addresses with Unscoped") + } + + if DB.Model(person).Association("Addresses").Clear(); DB.Model(person).Association("Addresses").Count() != 0 { + t.Errorf("Should deleted all addresses") + } +} diff --git a/main.go b/main.go index 5f90a146..71477830 100644 --- a/main.go +++ b/main.go @@ -481,6 +481,7 @@ func (s *DB) SetJoinTableHandler(joinTableHandler JoinTableHandler, tables ...st if len(tables) > 0 { for _, table := range tables { s.parent.joinTableHandlers[table] = joinTableHandler + s.Table(table).AutoMigrate(joinTableHandler) } } else { s.parent.joinTableHandlers["*"] = joinTableHandler diff --git a/scope_private.go b/scope_private.go index c69149c8..cb5c0f5e 100644 --- a/scope_private.go +++ b/scope_private.go @@ -439,18 +439,17 @@ func (scope *Scope) related(value interface{}, foreignKeys ...string) *Scope { } func (scope *Scope) createJoinTable(field *StructField) { - if field.Relationship != nil && field.Relationship.JoinTable != "" { - if !scope.Dialect().HasTable(scope, field.Relationship.JoinTable) { - newScope := scope.db.NewScope("") + if relationship := field.Relationship; relationship != nil && relationship.JoinTable != "" { + if !scope.Dialect().HasTable(scope, relationship.JoinTable) { primaryKeySqlType := scope.Dialect().SqlTag(scope.PrimaryKeyField().Field, 255) - newScope.Raw(fmt.Sprintf("CREATE TABLE %v (%v)", - field.Relationship.JoinTable, + scope.Err(scope.NewDB().Exec(fmt.Sprintf("CREATE TABLE %v (%v)", + scope.Quote(relationship.JoinTable), strings.Join([]string{ - scope.Quote(field.Relationship.ForeignDBName) + " " + primaryKeySqlType, - scope.Quote(field.Relationship.AssociationForeignDBName) + " " + primaryKeySqlType}, ",")), - ).Exec() - scope.Err(newScope.db.Error) + scope.Quote(relationship.ForeignDBName) + " " + primaryKeySqlType, + scope.Quote(relationship.AssociationForeignDBName) + " " + primaryKeySqlType}, ",")), + ).Error) } + scope.NewDB().Table(relationship.JoinTable).AutoMigrate(scope.db.GetJoinTableHandler(relationship.JoinTable)) } }