Search code examples
goforeign-keyspreloadgo-gorm

Golang gorm preloading


I'm writing my first app in golang, so sorry for newbie question, but I wasn't able to find the solution for the following problem:

I have two tables, position and attachment. Each position can have multiple attachments. Here is my model:

type Positions struct {
    Sys_id     int `gorm:"AUTO_INCREMENT" gorm:"column:sys_id" json:"sys_id,omitempty"`
    Name string `gorm:"size:120" gorm:"column:name" json:"name,omitempty"`
    OpenPositions int `gorm:"column:open_positions" json:"open_positions,omitempty"`
    ContactList string `gorm:"size:1000" gorm:"column:contact_list" json:"contact_list,omitempty"`
    Attachments []Attachment `gorm:"ForeignKey:RecordId"`
}

type Attachment struct {
    Sys_id     int `gorm:"AUTO_INCREMENT" gorm:"column:sys_id" json:"sys_id"`
    Name string `gorm:"size:255" gorm:"column: name" json:"name"`
    File string `gorm:"size:255" gorm:"column:file" json:"file"`
    RecordId int `gorm:"column:record_id" json:"record_id"`
    Table string `gorm:"size:255" gorm:"column:table" json:"table"`
    // ...
}

I want to query the db and get positions with attachments

positions2 := []models.Positions{}
err := db.Where("open_positions > ?", 0).Preload("Attachments", "`table` = ?", "user_position").Find(&positions2)
if err != nil {
    log.WithFields(log.Fields{
        "type": "queryerr",
        "msg": err,
    }).Error("faked up query")
}

Result of this query - I get positions correctly but the attachments are empty.

(can't preload field Attachments for models.Positions) level=error msg="faked up query" msg=&{0xc04200aca0 can't preload field Attachments for models.Positions 6 0xc042187e40 0xc042187d90 0xc0422cd4a0 0 {0xc042225130} false map[] map[] false}

Thanks in advance for help


Solution

  • Models in your example have custom primary column names. So, when only ForeignKey set for "has_many" association, Gorm trying to find Position's column Attachment.RecordId refers to. By default it uses Position as prefix and Id as column name for this. But neither RecordId column has prefix Position nor Position model has column Id, so it fails.

    In such case for "has_many" association you should specify both Foreign Key and Association Foreign Key.

    In your example Association Foreign Key is the Position.Sys_id column and Attachment.RecordId refers to it.

    So it should be fixed just by adding Association foreign key:

    Attachments   []Attachment `gorm:"ForeignKey:RecordId;AssociationForeignKey:sys_id"`