Add Append support for other associations
This commit is contained in:
parent
4677215ef4
commit
0ce635cc67
@ -29,42 +29,53 @@ func (association *Association) Find(value interface{}) *Association {
|
|||||||
func (association *Association) Append(values ...interface{}) *Association {
|
func (association *Association) Append(values ...interface{}) *Association {
|
||||||
scope := association.Scope
|
scope := association.Scope
|
||||||
field := association.Field
|
field := association.Field
|
||||||
|
relationship := association.Field.Relationship
|
||||||
|
|
||||||
createJoinTable := func(reflectValue reflect.Value) {
|
saveAssociation := func(reflectValue reflect.Value) {
|
||||||
var value = reflectValue.Interface()
|
// value has to been pointer
|
||||||
if reflectValue.Kind() != reflect.Ptr {
|
if reflectValue.Kind() != reflect.Ptr {
|
||||||
reflectPtr := reflect.New(reflectValue.Type())
|
reflectPtr := reflect.New(reflectValue.Type())
|
||||||
reflectPtr.Elem().Set(reflectValue)
|
reflectPtr.Elem().Set(reflectValue)
|
||||||
value = reflectPtr.Interface()
|
reflectValue = reflectPtr
|
||||||
}
|
}
|
||||||
|
|
||||||
if scope.New(value).PrimaryKeyZero() {
|
// value has to been saved
|
||||||
scope.NewDB().Save(value)
|
if scope.New(reflectValue.Interface()).PrimaryKeyZero() {
|
||||||
|
scope.NewDB().Save(reflectValue.Interface())
|
||||||
}
|
}
|
||||||
|
|
||||||
relationship := association.Field.Relationship
|
// Assign Fields
|
||||||
association.setErr(relationship.JoinTableHandler.Add(relationship.JoinTableHandler, scope.NewDB(), scope.Value, value))
|
fieldType := field.Field.Type()
|
||||||
|
if reflectValue.Type().AssignableTo(fieldType) {
|
||||||
|
field.Set(reflectValue)
|
||||||
|
} else if reflectValue.Type().Elem().AssignableTo(fieldType) {
|
||||||
|
field.Set(reflectValue.Elem())
|
||||||
|
} else if fieldType.Kind() == reflect.Slice {
|
||||||
|
if reflectValue.Type().AssignableTo(fieldType.Elem()) {
|
||||||
|
field.Set(reflect.Append(field.Field, reflectValue))
|
||||||
|
} else if reflectValue.Type().Elem().AssignableTo(fieldType.Elem()) {
|
||||||
|
field.Set(reflect.Append(field.Field, reflectValue.Elem()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
result := reflect.ValueOf(value)
|
if relationship.Kind == "many_to_many" {
|
||||||
fieldElemType := field.Field.Type().Elem()
|
association.setErr(relationship.JoinTableHandler.Add(relationship.JoinTableHandler, scope.NewDB(), scope.Value, reflectValue.Interface()))
|
||||||
if result.Type().AssignableTo(fieldElemType) {
|
} else {
|
||||||
field.Set(reflect.Append(field.Field, result))
|
association.setErr(scope.NewDB().Select(field.Name).Save(scope.Value).Error)
|
||||||
} else if result.Type().Elem().AssignableTo(fieldElemType) {
|
|
||||||
field.Set(reflect.Append(field.Field, result.Elem()))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, value := range values {
|
for _, value := range values {
|
||||||
reflectValue := reflect.Indirect(reflect.ValueOf(value))
|
reflectValue := reflect.ValueOf(value)
|
||||||
|
indirectReflectValue := reflect.Indirect(reflectValue)
|
||||||
if reflectValue.Kind() == reflect.Struct {
|
if indirectReflectValue.Kind() == reflect.Struct {
|
||||||
createJoinTable(reflectValue)
|
saveAssociation(reflectValue)
|
||||||
} else if reflectValue.Kind() == reflect.Slice {
|
} else if indirectReflectValue.Kind() == reflect.Slice {
|
||||||
for i := 0; i < reflectValue.Len(); i++ {
|
for i := 0; i < indirectReflectValue.Len(); i++ {
|
||||||
createJoinTable(reflectValue.Index(i))
|
saveAssociation(indirectReflectValue.Index(i))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
association.setErr(errors.New("invalid association type"))
|
association.setErr(errors.New("invalid value type"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return association
|
return association
|
||||||
|
@ -5,6 +5,66 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestHasOne(t *testing.T) {
|
||||||
|
DB.DropTable(Category{}, Post{})
|
||||||
|
DB.CreateTable(Category{}, Post{})
|
||||||
|
|
||||||
|
post := Post{
|
||||||
|
Title: "post 1",
|
||||||
|
Body: "body 1",
|
||||||
|
Category: Category{Name: "Category 1"},
|
||||||
|
MainCategory: Category{Name: "Main Category 1"},
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := DB.Save(&post).Error; err != nil {
|
||||||
|
t.Errorf("Got errors when save post", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query
|
||||||
|
var category Category
|
||||||
|
DB.Model(&post).Association("Category").Find(&category)
|
||||||
|
if category.Name != "Category 1" {
|
||||||
|
t.Errorf("Query has one relations with Association")
|
||||||
|
}
|
||||||
|
|
||||||
|
var category1 Category
|
||||||
|
DB.Model(&post).Related(&category1)
|
||||||
|
if category1.Name != "Category 1" {
|
||||||
|
t.Errorf("Query has one relations with Related")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append
|
||||||
|
var category2 = Category{
|
||||||
|
Name: "Category 2",
|
||||||
|
}
|
||||||
|
DB.Model(&post).Association("Category").Append(&category2)
|
||||||
|
|
||||||
|
if category2.Id == 0 {
|
||||||
|
t.Errorf("Category should has ID when created with Append")
|
||||||
|
}
|
||||||
|
|
||||||
|
var category21 Category
|
||||||
|
DB.Model(&post).Related(&category21)
|
||||||
|
|
||||||
|
if category21.Name != "Category 2" {
|
||||||
|
t.Errorf("Category should be updated with Append")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace
|
||||||
|
// DB.Model(&post).Association("Category").Replace(&Category{
|
||||||
|
// Name: "Category 3",
|
||||||
|
// })
|
||||||
|
|
||||||
|
// var category3 Category
|
||||||
|
// DB.Model(&post).Related(&category3)
|
||||||
|
// if category3.Name != "Category 3" {
|
||||||
|
// t.Errorf("Category should be updated with Replace")
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Delete
|
||||||
|
// Clear
|
||||||
|
}
|
||||||
|
|
||||||
func TestHasOneAndHasManyAssociation(t *testing.T) {
|
func TestHasOneAndHasManyAssociation(t *testing.T) {
|
||||||
DB.DropTable(Category{}, Post{}, Comment{})
|
DB.DropTable(Category{}, Post{}, Comment{})
|
||||||
DB.CreateTable(Category{}, Post{}, Comment{})
|
DB.CreateTable(Category{}, Post{}, Comment{})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user