GORM Playground Link

https://github.com/go-gorm/playground/pull/467

Description

Using

github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
github.com/jackc/pgx/v4 v4.15.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/mattn/go-sqlite3 v1.14.12 // indirect
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect
gorm.io/driver/mysql v1.3.3
gorm.io/driver/postgres v1.3.4
gorm.io/driver/sqlite v1.3.1
gorm.io/driver/sqlserver v1.3.2
gorm.io/gorm v1.23.4

User case The primary key of a struct may contain the struct name as a substring. For instance:

type Vehicle struct {
    VehicleID string `gorm:"primarykey"`
}

You may want to create a struct that belongs to the previous struct. For instance:

type ParkingSpot struct {
    ID        string `gorm:"primarykey"`
    VehicleVehicleID string
    Vehicle   Vehicle
}

but the field VehicleVehicleID is pedantic and VehicleID may be desirable. Following the instructions to override foreign key to yield the foreign key name VehicleID should result in something like this:

type ParkingSpot struct {
    ID        string `gorm:"primarykey"`
    VehicleID string
    Vehicle   Vehicle `gorm:"foreignKey:VehicleID"`
}

Expected results Allow additional notation to support this naming convention, or a fix. Otherwise if either are infeasible, there should be documentation stating that the foreign key field cannot be equal to the primary key of the assigned struct.

Actual results

/main_test.go:22 ERROR: insert or update on table "vehicles" violates foreign key constraint "fk_parking_spots_vehicle" (SQLSTATE 23503

Comment From: a631807682

 type ParkingSpot struct {
        ID        string `gorm:"primarykey"`
        VehicleID string
-       Vehicle   Vehicle `gorm:"foreignKey:VehicleID"`
+       Vehicle   Vehicle `gorm:"references:VehicleID"`
 }

gorm will guess the relationship. If there may be a belongs to and has one relationship at the same time, any guess may be wrong (if the primary key and foreign key names are the same), we need to specify references in the belongs to relationship. We will add instructions to the documentation.

Comment From: samc1213

I was having a somewhat related issue with the below:

type PrimaryKeyType struct {
    FkStr string `gorm:"primaryKey;not null;default:null"`
}

type ForeignKeyType struct {
    OtherKey       string `gorm:"primaryKey;not null;default:null"`
    FkStr          string
    PrimaryKeyType *PrimaryKeyType `gorm:"foreignKey:FkStr"`
}

With this code, PrimaryKeyType has a foreign key TO the ForeignKeyType. In order to reverse the direction of the foreign key, I added the belongsTo tag:

type PrimaryKeyType struct {
    FkStr string `gorm:"primaryKey;not null;default:null"`
}

type ForeignKeyType struct {
    OtherKey       string `gorm:"primaryKey;not null;default:null"`
    FkStr          string
    PrimaryKeyType *PrimaryKeyType `gorm:"foreignKey:FkStr;belongsTo"`  // see extra tag here!!
}