forked from mirror/gorm
Support include struct type in the foreign key to avoid ambiguous
This commit is contained in:
parent
1ad419004f
commit
0f3a9a8d02
|
@ -419,38 +419,50 @@ func (scope *Scope) typeName() string {
|
||||||
|
|
||||||
func (scope *Scope) related(value interface{}, foreignKeys ...string) *Scope {
|
func (scope *Scope) related(value interface{}, foreignKeys ...string) *Scope {
|
||||||
toScope := scope.db.NewScope(value)
|
toScope := scope.db.NewScope(value)
|
||||||
|
fromScopeType := scope.typeName()
|
||||||
|
toScopeType := toScope.typeName()
|
||||||
|
scopeType := ""
|
||||||
|
|
||||||
for _, foreignKey := range append(foreignKeys, toScope.typeName()+"Id", scope.typeName()+"Id") {
|
for _, foreignKey := range append(foreignKeys, toScope.typeName()+"Id", scope.typeName()+"Id") {
|
||||||
if field, ok := scope.FieldByName(foreignKey); ok {
|
if keys := strings.Split(foreignKey, "."); len(keys) > 1 {
|
||||||
relationship := field.Relationship
|
scopeType = keys[0]
|
||||||
if relationship != nil && relationship.ForeignKey != "" {
|
foreignKey = keys[1]
|
||||||
foreignKey = relationship.ForeignKey
|
}
|
||||||
|
|
||||||
if relationship.Kind == "many_to_many" {
|
if scopeType == "" || scopeType == fromScopeType {
|
||||||
joinSql := fmt.Sprintf(
|
if field, ok := scope.FieldByName(foreignKey); ok {
|
||||||
"INNER JOIN %v ON %v.%v = %v.%v",
|
relationship := field.Relationship
|
||||||
scope.Quote(relationship.JoinTable),
|
if relationship != nil && relationship.ForeignKey != "" {
|
||||||
scope.Quote(relationship.JoinTable),
|
foreignKey = relationship.ForeignKey
|
||||||
scope.Quote(ToSnake(relationship.AssociationForeignKey)),
|
|
||||||
toScope.QuotedTableName(),
|
if relationship.Kind == "many_to_many" {
|
||||||
scope.Quote(toScope.PrimaryKey()))
|
joinSql := fmt.Sprintf(
|
||||||
whereSql := fmt.Sprintf("%v.%v = ?", scope.Quote(relationship.JoinTable), scope.Quote(ToSnake(relationship.ForeignKey)))
|
"INNER JOIN %v ON %v.%v = %v.%v",
|
||||||
toScope.db.Joins(joinSql).Where(whereSql, scope.PrimaryKeyValue()).Find(value)
|
scope.Quote(relationship.JoinTable),
|
||||||
|
scope.Quote(relationship.JoinTable),
|
||||||
|
scope.Quote(ToSnake(relationship.AssociationForeignKey)),
|
||||||
|
toScope.QuotedTableName(),
|
||||||
|
scope.Quote(toScope.PrimaryKey()))
|
||||||
|
whereSql := fmt.Sprintf("%v.%v = ?", scope.Quote(relationship.JoinTable), scope.Quote(ToSnake(relationship.ForeignKey)))
|
||||||
|
toScope.db.Joins(joinSql).Where(whereSql, scope.PrimaryKeyValue()).Find(value)
|
||||||
|
return scope
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// has one
|
||||||
|
if foreignValue, ok := scope.FieldValueByName(foreignKey); ok {
|
||||||
|
toScope.inlineCondition(foreignValue).callCallbacks(scope.db.parent.callback.queries)
|
||||||
return scope
|
return scope
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// has one
|
|
||||||
if foreignValue, ok := scope.FieldValueByName(foreignKey); ok {
|
|
||||||
toScope.inlineCondition(foreignValue).callCallbacks(scope.db.parent.callback.queries)
|
|
||||||
return scope
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// has many
|
if scopeType == "" || scopeType == toScopeType {
|
||||||
if toScope.HasColumn(foreignKey) {
|
// has many
|
||||||
sql := fmt.Sprintf("%v = ?", scope.Quote(ToSnake(foreignKey)))
|
if toScope.HasColumn(foreignKey) {
|
||||||
return toScope.inlineCondition(sql, scope.PrimaryKeyValue()).callCallbacks(scope.db.parent.callback.queries)
|
sql := fmt.Sprintf("%v = ?", scope.Quote(ToSnake(foreignKey)))
|
||||||
|
return toScope.inlineCondition(sql, scope.PrimaryKeyValue()).callCallbacks(scope.db.parent.callback.queries)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scope.Err(fmt.Errorf("invalid association %v", foreignKeys))
|
scope.Err(fmt.Errorf("invalid association %v", foreignKeys))
|
||||||
|
|
Loading…
Reference in New Issue