Support include struct type in the foreign key to avoid ambiguous

This commit is contained in:
Jinzhu 2014-09-08 11:19:05 +08:00
parent 1ad419004f
commit 0f3a9a8d02
1 changed files with 36 additions and 24 deletions

View File

@ -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))