forked from mirror/gorm
Add polymorphic_test.go
This commit is contained in:
parent
e615aab232
commit
6864d5e5bd
|
@ -15,7 +15,7 @@ type Association struct {
|
||||||
Field *Field
|
Field *Field
|
||||||
}
|
}
|
||||||
|
|
||||||
func (association *Association) err(err error) *Association {
|
func (association *Association) setErr(err error) *Association {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
association.Error = err
|
association.Error = err
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ func (association *Association) err(err error) *Association {
|
||||||
|
|
||||||
func (association *Association) Find(value interface{}) *Association {
|
func (association *Association) Find(value interface{}) *Association {
|
||||||
association.Scope.related(value, association.Column)
|
association.Scope.related(value, association.Column)
|
||||||
return association.err(association.Scope.db.Error)
|
return association.setErr(association.Scope.db.Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (association *Association) Append(values ...interface{}) *Association {
|
func (association *Association) Append(values ...interface{}) *Association {
|
||||||
|
@ -53,11 +53,11 @@ func (association *Association) Append(values ...interface{}) *Association {
|
||||||
} else if reflectvalue.Kind() == reflect.Slice && fieldType.Elem() == reflectvalue.Type().Elem() {
|
} else if reflectvalue.Kind() == reflect.Slice && fieldType.Elem() == reflectvalue.Type().Elem() {
|
||||||
field.Set(reflect.AppendSlice(field.Field, reflectvalue))
|
field.Set(reflect.AppendSlice(field.Field, reflectvalue))
|
||||||
} else {
|
} else {
|
||||||
association.err(errors.New("invalid association type"))
|
association.setErr(errors.New("invalid association type"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scope.callCallbacks(scope.db.parent.callback.updates)
|
scope.callCallbacks(scope.db.parent.callback.updates)
|
||||||
return association.err(scope.db.Error)
|
return association.setErr(scope.db.Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (association *Association) getPrimaryKeys(values ...interface{}) []interface{} {
|
func (association *Association) getPrimaryKeys(values ...interface{}) []interface{} {
|
||||||
|
@ -92,7 +92,7 @@ func (association *Association) Delete(values ...interface{}) *Association {
|
||||||
primaryKeys := association.getPrimaryKeys(values...)
|
primaryKeys := association.getPrimaryKeys(values...)
|
||||||
|
|
||||||
if len(primaryKeys) == 0 {
|
if len(primaryKeys) == 0 {
|
||||||
association.err(errors.New("no primary key found"))
|
association.setErr(errors.New("no primary key found"))
|
||||||
} else {
|
} else {
|
||||||
relationship := association.Field.Relationship
|
relationship := association.Field.Relationship
|
||||||
// many to many
|
// many to many
|
||||||
|
@ -104,7 +104,7 @@ func (association *Association) Delete(values ...interface{}) *Association {
|
||||||
association.Scope.db.Model("").Table(relationship.JoinTable).
|
association.Scope.db.Model("").Table(relationship.JoinTable).
|
||||||
Where(whereSql, association.PrimaryKey, primaryKeys).Delete("")
|
Where(whereSql, association.PrimaryKey, primaryKeys).Delete("")
|
||||||
} else {
|
} else {
|
||||||
association.err(errors.New("delete only support many to many"))
|
association.setErr(errors.New("delete only support many to many"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return association
|
return association
|
||||||
|
@ -143,7 +143,7 @@ func (association *Association) Replace(values ...interface{}) *Association {
|
||||||
|
|
||||||
scope.db.Model("").Table(relationship.JoinTable).Where(whereSql, association.PrimaryKey, addedPrimaryKeys).Delete("")
|
scope.db.Model("").Table(relationship.JoinTable).Where(whereSql, association.PrimaryKey, addedPrimaryKeys).Delete("")
|
||||||
} else {
|
} else {
|
||||||
association.err(errors.New("replace only support many to many"))
|
association.setErr(errors.New("replace only support many to many"))
|
||||||
}
|
}
|
||||||
return association
|
return association
|
||||||
}
|
}
|
||||||
|
@ -155,7 +155,7 @@ func (association *Association) Clear() *Association {
|
||||||
whereSql := fmt.Sprintf("%v.%v = ?", relationship.JoinTable, scope.Quote(ToSnake(relationship.ForeignKey)))
|
whereSql := fmt.Sprintf("%v.%v = ?", relationship.JoinTable, scope.Quote(ToSnake(relationship.ForeignKey)))
|
||||||
scope.db.Model("").Table(relationship.JoinTable).Where(whereSql, association.PrimaryKey).Delete("")
|
scope.db.Model("").Table(relationship.JoinTable).Where(whereSql, association.PrimaryKey).Delete("")
|
||||||
} else {
|
} else {
|
||||||
association.err(errors.New("clear only support many to many"))
|
association.setErr(errors.New("clear only support many to many"))
|
||||||
}
|
}
|
||||||
return association
|
return association
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,30 +2,6 @@ package gorm_test
|
||||||
|
|
||||||
import "testing"
|
import "testing"
|
||||||
|
|
||||||
import "github.com/jinzhu/gorm"
|
|
||||||
|
|
||||||
type Cat struct {
|
|
||||||
Id int
|
|
||||||
Name string
|
|
||||||
Toy Toy `gorm:"polymorphic:Owner;"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Dog struct {
|
|
||||||
Id int
|
|
||||||
Name string
|
|
||||||
Toys []Toy `gorm:"polymorphic:Owner;"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Toy struct {
|
|
||||||
Id int
|
|
||||||
Name string
|
|
||||||
OwnerId int
|
|
||||||
OwnerType string
|
|
||||||
|
|
||||||
// Define the owner type as a belongs_to so we can ensure it throws an error
|
|
||||||
Owner Dog `gorm:"foreignkey:owner_id; foreigntype:owner_type;"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHasOneAndHasManyAssociation(t *testing.T) {
|
func TestHasOneAndHasManyAssociation(t *testing.T) {
|
||||||
DB.DropTable(Category{})
|
DB.DropTable(Category{})
|
||||||
DB.DropTable(Post{})
|
DB.DropTable(Post{})
|
||||||
|
@ -240,45 +216,3 @@ func TestManyToMany(t *testing.T) {
|
||||||
t.Errorf("Relations should be cleared")
|
t.Errorf("Relations should be cleared")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPolymorphic(t *testing.T) {
|
|
||||||
DB.DropTableIfExists(Cat{})
|
|
||||||
DB.DropTableIfExists(Dog{})
|
|
||||||
DB.DropTableIfExists(Toy{})
|
|
||||||
|
|
||||||
DB.AutoMigrate(&Cat{})
|
|
||||||
DB.AutoMigrate(&Dog{})
|
|
||||||
DB.AutoMigrate(&Toy{})
|
|
||||||
|
|
||||||
cat := Cat{Name: "Mr. Bigglesworth", Toy: Toy{Name: "cat nip"}}
|
|
||||||
dog := Dog{Name: "Pluto", Toys: []Toy{Toy{Name: "orange ball"}, Toy{Name: "yellow ball"}}}
|
|
||||||
DB.Save(&cat).Save(&dog)
|
|
||||||
|
|
||||||
var catToys []Toy
|
|
||||||
if err := DB.Model(&cat).Related(&catToys, "Toy").Error; err == gorm.RecordNotFound {
|
|
||||||
t.Errorf("Did not find any has one polymorphic association")
|
|
||||||
} else if len(catToys) != 1 {
|
|
||||||
t.Errorf("Should have found only one polymorphic has one association")
|
|
||||||
} else if catToys[0].Name != cat.Toy.Name {
|
|
||||||
t.Errorf("Should have found the proper has one polymorphic association")
|
|
||||||
}
|
|
||||||
|
|
||||||
var dogToys []Toy
|
|
||||||
if err := DB.Model(&dog).Related(&dogToys, "Toys").Error; err == gorm.RecordNotFound {
|
|
||||||
t.Errorf("Did not find any polymorphic has many associations")
|
|
||||||
} else if len(dogToys) != len(dog.Toys) {
|
|
||||||
t.Errorf("Should have found all polymorphic has many associations")
|
|
||||||
}
|
|
||||||
|
|
||||||
if DB.Model(&cat).Association("Toy").Count() != 1 {
|
|
||||||
t.Errorf("Should return one polymorphic has one association")
|
|
||||||
}
|
|
||||||
|
|
||||||
if DB.Model(&dog).Association("Toys").Count() != 2 {
|
|
||||||
t.Errorf("Should return two polymorphic has many associations")
|
|
||||||
}
|
|
||||||
|
|
||||||
if DB.Model(&Toy{OwnerId: dog.Id, OwnerType: "dog"}).Related(&dog, "Owner").Error == nil {
|
|
||||||
t.Errorf("Should have thrown unsupported belongs_to error")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
2
main.go
2
main.go
|
@ -429,7 +429,7 @@ func (s *DB) Association(column string) *Association {
|
||||||
|
|
||||||
var field *Field
|
var field *Field
|
||||||
var ok bool
|
var ok bool
|
||||||
if field, ok = scope.FieldByName(SnakeToUpperCamel(column)); ok {
|
if field, ok = scope.FieldByName(column); ok {
|
||||||
if field.Relationship == nil || field.Relationship.ForeignKey == "" {
|
if field.Relationship == nil || field.Relationship.ForeignKey == "" {
|
||||||
scope.Err(fmt.Errorf("invalid association %v for %v", column, scope.IndirectValue().Type()))
|
scope.Err(fmt.Errorf("invalid association %v for %v", column, scope.IndirectValue().Type()))
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
package gorm_test
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
type Cat struct {
|
||||||
|
Id int
|
||||||
|
Name string
|
||||||
|
Toy Toy `gorm:"polymorphic:Owner;"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Dog struct {
|
||||||
|
Id int
|
||||||
|
Name string
|
||||||
|
Toys []Toy `gorm:"polymorphic:Owner;"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Toy struct {
|
||||||
|
Id int
|
||||||
|
Name string
|
||||||
|
OwnerId int
|
||||||
|
OwnerType string
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPolymorphic(t *testing.T) {
|
||||||
|
DB.AutoMigrate(&Cat{})
|
||||||
|
DB.AutoMigrate(&Dog{})
|
||||||
|
DB.AutoMigrate(&Toy{})
|
||||||
|
|
||||||
|
cat := Cat{Name: "Mr. Bigglesworth", Toy: Toy{Name: "cat nip"}}
|
||||||
|
dog := Dog{Name: "Pluto", Toys: []Toy{Toy{Name: "orange ball"}, Toy{Name: "yellow ball"}}}
|
||||||
|
DB.Save(&cat).Save(&dog)
|
||||||
|
|
||||||
|
var catToys []Toy
|
||||||
|
if DB.Model(&cat).Related(&catToys, "Toy").RecordNotFound() {
|
||||||
|
t.Errorf("Did not find any has one polymorphic association")
|
||||||
|
} else if len(catToys) != 1 {
|
||||||
|
t.Errorf("Should have found only one polymorphic has one association")
|
||||||
|
} else if catToys[0].Name != cat.Toy.Name {
|
||||||
|
t.Errorf("Should have found the proper has one polymorphic association")
|
||||||
|
}
|
||||||
|
|
||||||
|
var dogToys []Toy
|
||||||
|
if DB.Model(&dog).Related(&dogToys, "Toys").RecordNotFound() {
|
||||||
|
t.Errorf("Did not find any polymorphic has many associations")
|
||||||
|
} else if len(dogToys) != len(dog.Toys) {
|
||||||
|
t.Errorf("Should have found all polymorphic has many associations")
|
||||||
|
}
|
||||||
|
|
||||||
|
if DB.Model(&cat).Association("Toy").Count() != 1 {
|
||||||
|
t.Errorf("Should return one polymorphic has one association")
|
||||||
|
}
|
||||||
|
|
||||||
|
if DB.Model(&dog).Association("Toys").Count() != 2 {
|
||||||
|
t.Errorf("Should return two polymorphic has many associations")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue