As the belongs_to Foreign Key document shows, my example code below should be work. But it always notice * invalid association * error.
What's wrong here? Thanks for help!
```golang
package main
import(
"log"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
type ApplicationGroup struct{
gorm.Model
Name string
}
type Application struct{
gorm.Model
Name string
GroupID int
Group ApplicationGroup `gorm:"foreignkey:GroupID"`
}
func main() {
db, err := gorm.Open("mysql", "root:root@tcp(localhost:3306)/dbname?charset=utf8")
if err != nil {
log.Fatal(err)
}
app := Application{GroupID: 123}
var group ApplicationGroup
q := db.Model(&app).Related(&group)
log.Println(q.Error) //invalid association []
}
`
maybe you can try this
q := db.Model(&app).Related(&group, "GroupID")
Yes, this works.
But I think it should get GroupID from the gorm tags, instead of manually specified.
I ran into this too, I have to specify it manually. @jinzhu shouldn't it use the gorm:"foreignkey" tag value?
same problem in version v1.9.14 @jinzhu
as per the source code:
// Related get related associations
func (s *DB) Related(value interface{}, foreignKeys ...string) *DB {
return s.NewScope(s.Value).related(value, foreignKeys...).db
}
func (scope *Scope) related(value interface{}, foreignKeys ...string) *Scope {
toScope := scope.db.NewScope(value)
tx := scope.db.Set("gorm:association:source", scope.Value)
for _, foreignKey := range append(foreignKeys, toScope.typeName()+"Id", scope.typeName()+"Id") {
fromField, _ := scope.FieldByName(foreignKey)
toField, _ := toScope.FieldByName(foreignKey)
if fromField != nil {
if relationship := fromField.Relationship; relationship != nil {
if relationship.Kind == "many_to_many" {
joinTableHandler := relationship.JoinTableHandler
scope.Err(joinTableHandler.JoinWith(joinTableHandler, tx, scope.Value).Find(value).Error)
} else if relationship.Kind == "belongs_to" {
for idx, foreignKey := range relationship.ForeignDBNames {
if field, ok := scope.FieldByName(foreignKey); ok {
tx = tx.Where(fmt.Sprintf("%v = ?", scope.Quote(relationship.AssociationForeignDBNames[idx])), field.Field.Interface())
}
}
scope.Err(tx.Find(value).Error)
} else if relationship.Kind == "has_many" || relationship.Kind == "has_one" {
for idx, foreignKey := range relationship.ForeignDBNames {
if field, ok := scope.FieldByName(relationship.AssociationForeignDBNames[idx]); ok {
tx = tx.Where(fmt.Sprintf("%v = ?", scope.Quote(foreignKey)), field.Field.Interface())
}
}
if relationship.PolymorphicType != "" {
tx = tx.Where(fmt.Sprintf("%v = ?", scope.Quote(relationship.PolymorphicDBName)), relationship.PolymorphicValue)
}
scope.Err(tx.Find(value).Error)
}
} else {
sql := fmt.Sprintf("%v = ?", scope.Quote(toScope.PrimaryKey()))
scope.Err(tx.Where(sql, fromField.Field.Interface()).Find(value).Error)
}
return scope
} else if toField != nil {
sql := fmt.Sprintf("%v = ?", scope.Quote(toField.DBName))
scope.Err(tx.Where(sql, scope.PrimaryKeyValue()).Find(value).Error)
return scope
}
}
scope.Err(fmt.Errorf("invalid association %v", foreignKeys))
return scope
}
the code tries to figure out the first possible field name that containing the foreign key in the following order:
the second argument when calling the function Related()
the type name of the owner or owned type, appended by Id
we can see it definitely ignores the tags foreignkey and association_foreignkey
@jinzhu
the official documentation is basically wrong:
To define a belongs to relationship, the foreign key must exists, default foreign key uses owner鈥檚 type name plus its primary key.
For the above example, to define a model that belongs to User, the foreign key should be UserID.
GORM provides a way to customize the foreign key, for example:
type User struct {
gorm.Model
Name string
}
type Profile struct {
gorm.Model
Name string
User User `gorm:"foreignkey:UserRefer"` // use UserRefer as foreign key
UserRefer uint
}
in fact, foreignkey has no use here!
Yes, there is an issue, when I design the Related method, I thought it as a method to query associations with user-specified foreign key, the auto guessing foreign key is just sugar.
It should be used like db.Related(&user, "User"), db.Model(&app).Related(&group, "Group")
But I think I am not going to fix this one, as we dropped the Related support in v2, refer:
https://github.com/go-gorm/gorm/wiki/GORM-V2-Release-Note-Draft#association-mode
Yes, there is an issue
you should at least point it out in the documentation. so many people encountered this bug before.
Actually it is mentioned in the document, but maybe not quite clear.

It should specified that it won't use the setting from tags to make it more clear
Most helpful comment
I ran into this too, I have to specify it manually. @jinzhu shouldn't it use the
gorm:"foreignkey"tag value?