Search code examples
gogo-gorm

GoLang GORM embedding struct from other table


I have 3 models, one embedded to another:

// same with db table "users" struct except UserEmail embedded
type User struct {
    ID      string `json:"id"`
    EmailID string `json:"-"`

    *UserEmail `json:",inline" gorm:"foreignKey:EmailID;references:UserEmailID"`
}

// not same with db table "email" struct
type UserEmail struct {
    UserEmailID string `json:"-"`
    UserEmail   string `json:"user_email"`
}

// same with db table "email" struct
type Email struct {
    ID    string `json:"id"`
    Email string `json:"email"`
}

I need preload data from 2 tables called users and emails.

My preload code looks like this, but cause error "ERROR: column users.email_id does not exist (SQLSTATE 42703)":

err = db.ORM.Model(&Users{}).
    Preload("UserEmail", func(db *gorm.DB) *gorm.DB {
        return db.Model(&Email{}).Select("id as user_email_id, email as user_email")
    }).
    Find(&resp).Error

Solution

  • can you provide the schema database, maybe the information will be very useful to help your problem.

    ERROR: column users.email_id does not exist (SQLSTATE 42703) indicates the column email_id does not exist in your users table.

    I think the column name is not email_id but user_email_id in your schema DB. Maybe your table users schema like this:

    | users           |
    | --------------- |
    | id              |
    | user_email_id   |
    

    and schema table user_emails like this:

    | user_emails     |
    | --------------- |
    | id              |
    | email           |
    

    If my database schema guess is correct, Maybe the fix would be something like this:

    type User struct {
        ID        string     `json:"id"`
        EmailID   string     `json:"-" gorm:"column:user_email_id"`
        UserEmail *UserEmail `json:",inline" gorm:"foreignKey:EmailID;references:UserEmailID"`
    }
    
    type UserEmail struct {
        UserEmailID string `json:"-" gorm:"column:id"`
        UserEmail   string `json:"user_email" gorm:"column:email"`
    }
    

    Add tag Column Name to keep your name struct attributes, and your preload don't need query sql alias for casting column id as user_email_id because already use tag Column Name, and the final code like this:

    err = db.ORM.Model(&User{}).Preload("UserEmail").Find(&resp).Error