mallix
mallix

Reputation: 1429

Golang GORM has many relationship

I have 2 simple entities, User has many Assets:

type User struct {
    UserId     int     `gorm:"PRIMARY_KEY"`
    Email      string  `gorm:"column:email"`
    FirstName  string  `gorm:"column:firstname"`
    LastName   string  `gorm:"column:lastname"`
    Assets     []Asset `gorm:"foreignkey:user_id"`
}

type Asset struct {
    AssetId int    `gorm:"PRIMARY_KEY"`
    UserId  int    `gorm:"column:user_id"`
    Slug    string `gorm:"column:slug"`
    Address string `gorm:"address"`
}

I want to get a user by the primary id and also collect the assets.

Following the documentation here: http://doc.gorm.io/associations.html#has-many I did the following which gives me an empty array although there are records:

var user app.User
var assets []app.Asset

err := r.DB.Where("user_id = ?", userId).First(&user).Error
if err != nil {
    return nil, err
}

r.DB.Model(&user).Related(&assets)

Changing from:

r.DB.Model(&user).Related(&assets)

to:

r.DB.Model(&user).Related(&user.Assets)

I retrieve a single Asset because GORM is retrieving by asset_id instead of by user_id for some reason. (so if the user_id is 10, it is getting an asset with asset_id -> 10)

What is the correct way to handle the relationship in this case ?

Upvotes: 0

Views: 8248

Answers (3)

Anis
Anis

Reputation: 3599

It's not an answer, just an update.

Maybe the problem you mentioned was a bug and fixed by now. The following pattern is working for me without any issue.

r.DB.Model(&user).Related(&user.Assets)

But a small difference with your schema, I didn't mention gorm:"foreignkey:user_id" explicitly. Just common naming convention is doing the job automatially.

Upvotes: 0

Nikhil Agrawal
Nikhil Agrawal

Reputation: 1

Preload() func can be used to load linked directly. Update on the code given :

var user app.User
var assets []app.Asset

err := r.DB.Where("user_id = ?", userId).Preload("Assets").First(&user).Error
if err != nil {
  return nil, err
}

Upvotes: 0

John Corry
John Corry

Reputation: 1577

I tried this that way too based on the docs and was unable to get it to work.

What ultimately worked for me was the Preload() func on the db.

Here's an example from some of my code:

err := GetDB().Preload("Ingredients").Find(&flavors).Error

Upvotes: 2

Related Questions