forked from mirror/gorm
Fix preload many2many problem when no search results, #688
This commit is contained in:
parent
edee5f5b75
commit
2f9abdcf02
|
@ -134,7 +134,6 @@ func (s JoinTableHandler) JoinWith(handler JoinTableHandlerInterface, db *DB, so
|
||||||
scope := db.NewScope(source)
|
scope := db.NewScope(source)
|
||||||
modelType := scope.GetModelStruct().ModelType
|
modelType := scope.GetModelStruct().ModelType
|
||||||
var joinConditions []string
|
var joinConditions []string
|
||||||
var queryConditions []string
|
|
||||||
var values []interface{}
|
var values []interface{}
|
||||||
if s.Source.ModelType == modelType {
|
if s.Source.ModelType == modelType {
|
||||||
destinationTableName := db.NewScope(reflect.New(s.Destination.ModelType).Interface()).QuotedTableName()
|
destinationTableName := db.NewScope(reflect.New(s.Destination.ModelType).Interface()).QuotedTableName()
|
||||||
|
@ -152,12 +151,15 @@ func (s JoinTableHandler) JoinWith(handler JoinTableHandlerInterface, db *DB, so
|
||||||
|
|
||||||
foreignFieldValues := scope.getColumnAsArray(foreignFieldNames)
|
foreignFieldValues := scope.getColumnAsArray(foreignFieldNames)
|
||||||
|
|
||||||
condString := fmt.Sprintf("%v in (%v)", toQueryCondition(scope, foreignDBNames), toQueryMarks(foreignFieldValues))
|
var condString string
|
||||||
|
if len(foreignFieldValues) > 0 {
|
||||||
|
condString = fmt.Sprintf("%v IN (%v)", toQueryCondition(scope, foreignDBNames), toQueryMarks(foreignFieldValues))
|
||||||
|
|
||||||
keys := scope.getColumnAsArray(foreignFieldNames)
|
keys := scope.getColumnAsArray(foreignFieldNames)
|
||||||
values = append(values, toQueryValues(keys))
|
values = append(values, toQueryValues(keys))
|
||||||
|
} else {
|
||||||
queryConditions = append(queryConditions, condString)
|
condString = fmt.Sprintf("1 <> 1")
|
||||||
|
}
|
||||||
|
|
||||||
return db.Joins(fmt.Sprintf("INNER JOIN %v ON %v", quotedTable, strings.Join(joinConditions, " AND "))).
|
return db.Joins(fmt.Sprintf("INNER JOIN %v ON %v", quotedTable, strings.Join(joinConditions, " AND "))).
|
||||||
Where(condString, toQueryValues(foreignFieldValues)...)
|
Where(condString, toQueryValues(foreignFieldValues)...)
|
||||||
|
|
|
@ -63,7 +63,7 @@ func Preload(scope *Scope) {
|
||||||
case "belongs_to":
|
case "belongs_to":
|
||||||
currentScope.handleBelongsToPreload(field, conditions)
|
currentScope.handleBelongsToPreload(field, conditions)
|
||||||
case "many_to_many":
|
case "many_to_many":
|
||||||
currentScope.handleHasManyToManyPreload(field, conditions)
|
currentScope.handleManyToManyPreload(field, conditions)
|
||||||
default:
|
default:
|
||||||
currentScope.Err(errors.New("not supported relation"))
|
currentScope.Err(errors.New("not supported relation"))
|
||||||
}
|
}
|
||||||
|
@ -191,9 +191,8 @@ func (scope *Scope) handleBelongsToPreload(field *Field, conditions []interface{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (scope *Scope) handleHasManyToManyPreload(field *Field, conditions []interface{}) {
|
func (scope *Scope) handleManyToManyPreload(field *Field, conditions []interface{}) {
|
||||||
relation := field.Relationship
|
relation := field.Relationship
|
||||||
|
|
||||||
joinTableHandler := relation.JoinTableHandler
|
joinTableHandler := relation.JoinTableHandler
|
||||||
destType := field.StructField.Struct.Type.Elem()
|
destType := field.StructField.Struct.Type.Elem()
|
||||||
var isPtr bool
|
var isPtr bool
|
||||||
|
@ -211,6 +210,7 @@ func (scope *Scope) handleHasManyToManyPreload(field *Field, conditions []interf
|
||||||
|
|
||||||
db := scope.NewDB().Table(scope.New(reflect.New(destType).Interface()).TableName()).Select("*")
|
db := scope.NewDB().Table(scope.New(reflect.New(destType).Interface()).TableName()).Select("*")
|
||||||
preloadJoinDB := joinTableHandler.JoinWith(joinTableHandler, db, scope.Value)
|
preloadJoinDB := joinTableHandler.JoinWith(joinTableHandler, db, scope.Value)
|
||||||
|
|
||||||
if len(conditions) > 0 {
|
if len(conditions) > 0 {
|
||||||
preloadJoinDB = preloadJoinDB.Where(conditions[0], conditions[1:]...)
|
preloadJoinDB = preloadJoinDB.Where(conditions[0], conditions[1:]...)
|
||||||
}
|
}
|
||||||
|
|
|
@ -689,6 +689,10 @@ func TestManyToManyPreloadWithMultiPrimaryKeys(t *testing.T) {
|
||||||
if !reflect.DeepEqual(got4, []Level2{got, got2}) {
|
if !reflect.DeepEqual(got4, []Level2{got, got2}) {
|
||||||
t.Errorf("got %s; want %s", toJSONString(got4), toJSONString([]Level2{got, got2}))
|
t.Errorf("got %s; want %s", toJSONString(got4), toJSONString([]Level2{got, got2}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := DB.Preload("Level1s").Find(&got4, "value IN (?)", []string{"non-existing"}).Error; err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestManyToManyPreloadForPointer(t *testing.T) {
|
func TestManyToManyPreloadForPointer(t *testing.T) {
|
||||||
|
|
Loading…
Reference in New Issue