Paul
Paul

Reputation: 343

One-to-many association

I'm having troubles with one-to-many associations in GORM. I have those two structures and I'd like to get one patient's full history. Here is my sample code:

type Patient struct {
    gorm.Model
    Prenom     string       `json:"prenom" gorm:"column:patient_prenom"`
    Nom        string       `json:"nom" gorm:"column:patient_nom"`
    Genre      string       `json:"genre" gorm:"column:patient_genre"`
    Naissance  string       `json:"naissance" gorm:"column:patient_naissance"`
    Historique []Historique `gorm:"ForeignKey:Fk_patient_id"`
}
type Historique struct {
    Fk_patient_id        string
    Date_consultation    string
    Fk_maladie_id        uint
    Fk_compte_medecin_id uint
    Patient              Patient
}

func GetPatientWithDiseases(id uint) (*Patient, error) {
    patient := &Patient{}
    //The line right there works so i can retrieve without the history
    //err := GetDB().Find(patient, id).Error
    db := GetDB().Preload("tt_historique").Find(patient)
    err := db.Error

    if err != nil {
        return nil, err
    }
    return patient, nil
}

Where "Historique" uses the foreign key of the patient (Fk_patient_id), and the Historique []Historique is the list of every Historique that should end up in the Patient struct after the query.

However I get this error can't preload field tt_historique for models.Patient. I've tried multiple syntaxes that I've found on Internet in the gorm specifications in the struct but nothing worked. I've only been developing using GO for 3 days and GORM is my first ORM, so maybe I'm missing something really obvious.

Upvotes: 0

Views: 83

Answers (1)

Emin Laletovic
Emin Laletovic

Reputation: 4324

Based on the presumption that tt_historique is your table name, there are a couple of things you need to take care of here.

By convention, go-gorm uses pluralized snake case struct names as database tables when constructing a SQL query. In your case, to preload the Historique []Historique field, it would look for the historiques table.

To override this, you need to implement the Tabler interface:

type Patient struct {
    gorm.Model
    Prenom     string       `json:"prenom" gorm:"column:patient_prenom"`
    Nom        string       `json:"nom" gorm:"column:patient_nom"`
    Genre      string       `json:"genre" gorm:"column:patient_genre"`
    Naissance  string       `json:"naissance" gorm:"column:patient_naissance"`
    Historique []Historique `gorm:"foreignKey:Fk_patient_id"`
}
type Historique struct {
    Fk_patient_id        string
    Date_consultation    string
    Fk_maladie_id        uint
    Fk_compte_medecin_id uint
    Patient              Patient
}

func (Historique) TableName() string {
  return "tt_historique"
}

Then, your query would look like this:

db := GetDB().Preload("Historique").Find(patient)

Upvotes: 2

Related Questions