In a scenario as follows that features many-to-many relationships but using custom keys I expected gorm to make use of the specified ForeignKey and AssociationForeignKey. The keys are specified the same way as in multi_primary_keys_test.go, yet they seem to get ignored.
type Foo struct {
ID int64 `gorm:"primary_key"`
Title string
// Note the custom_bar_id and custom_foo_id which are ignored by GORM.
AllocatedBars []*Bar `gorm:"many2many:foo_allocated_bars;ForeignKey:id,custom_bar_id;AssociationForeignKey:id,custom_foo_id"`
}
type Bar struct {
ID int64 `gorm:"primary_key"`
}
Note: The full example source is available as a gist.
Expected Result
With the ForeignKey:id,custom_bar_id;AssociationForeignKey:id,custom_foo_id" keys defined gorm should be using custom_bar_id and custom_foo_id in the association table foo_allocated_bars.
Gorm ignores the keys altogether and creates default key names from the types table name, foo_id and bar_id.
This may be related to issue #955.
+1
Just hacked my workaround into my local model_struct (for the exact same use case as yours it seems):
joinTableDBName := ToDBName(reflectType.Name()) + "_" + foreignField.DBName
if len(foreignKeys) >= 2 {
joinTableDBName = foreignKeys[len(foreignKeys)-1]
}
I know that that's not a permanent, nor a pretty solution but it fixes the problem for me.
We just spent a while dealing with this issue as well. Any updates from the maintainers? @jinzhu
m2m doesn't support customize foreign keys in the join table rightnow, the tag ForeignKey:id,locale here means Blog having two foreign keys (ID, Locale)
If you really want to customize the column names in the join table, you could have a JoinModel, and customize its columns like below:
package main
import (
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/jinzhu/gorm"
_ "github.com/lib/pq"
_ "github.com/mattn/go-sqlite3"
)
var db *gorm.DB
type Foo struct {
ID int64 `gorm:"primary_key"`
Title string
// Note the custom_bar_id and custom_foo_id which are ignored by GORM.
FooBars []FooBar
}
type FooBar struct {
FooID uint `gorm:"column:custom_foo_id"`
BarID uint `gorm:"column:custom_bar_id"`
Bar Bar
}
type Bar struct {
ID int64 `gorm:"primary_key"`
Name string
}
func main() {
// db, _ = gorm.Open("postgres", fmt.Sprintf("user=gorm password=gorm DB.name=gorm sslmode=disable"))
// db, _ = gorm.Open("mysql", fmt.Sprintf("user=gorm password=gorm DB.name=gorm sslmode=disable"))
db, _ = gorm.Open("sqlite3", "gorm.db")
db.LogMode(true)
db.DropTableIfExists(&Foo{}, &FooBar{}, &Bar{})
db.AutoMigrate(&Foo{}, &FooBar{}, &Bar{})
foo := Foo{
Title: "foo",
FooBars: []FooBar{{Bar: Bar{Name: "bar"}}, {Bar: Bar{Name: "bar2"}}},
}
db.Save(&foo)
var foo2 Foo
db.Preload("FooBars.Bar").First(&foo2)
fmt.Printf("%+v \n", foo2)
}
Most helpful comment
m2m doesn't support customize foreign keys in the join table rightnow, the tag
ForeignKey:id,localehere means Blog having two foreign keys (ID, Locale)If you really want to customize the column names in the join table, you could have a JoinModel, and customize its columns like below: