How to create a row with GORM and associate the new ID created in the row of another table?

I have the following tables:

type OldData struct {
	Name string
	Date time.Time
}

type NewData struct {
	gorm.Model
	Name string
}

type History struct {
	ID uint
	Date time.Time
}

So then I have a situation similar to this:

oldData := &OldData{
	Name: "Julia",
	Date: time.Now(),
}

newData := &NewData{
	Name: oldData.Name,
}

history := &History{
	Date: oldData.Date,
}

How do I create the new newData row but at the same time have history.ID be the same ID as newData.ID? How do I make a relationship so that if I delete the newData.ID row the history.ID row is also deleted from the historys table?

I’m looking for a way to relate newData to history that are stored in two different tables.
db.Create(newData)

According you describe the situation, history and NewData have to have the same number of records and I guess that the Id fields are autonumeric so there a high probabilty we can get different id for the same record number. You could do :

  • Merge NewData and History in one table (Not sure about this because i do not know all your business requirements)
  • Add a Foreign Key in history to stablish a relationship with NewData. This way never mind if they did no have the same id, buy you are positive taht you can access the right record in NewData from History.

Just my two cents…

NewData and History are always created at the same time, my problem is associating the ID and the Date when creating a new one, both tables have the same number of ID’s, your second option seems to me to be very close to what I am looking for, can you please show me some code?

I thibk you can use this approach :

  1. Add this annotation to you ID field in history

    ID uint64 gorm:"primary_key;auto_increment;not_null"

You can also start from the NewData struct, just adding the ID with above definition

  1. Issue a create operation for the history table

    history := History { Date : time.Now() }
    result := db.Create(&history)

  2. Now history has the newesst Id so assign an ID field to your NewData struct and creates the record

    newData := NewData { Bame : “Your Name”, historyID : history.ID }
    result := db.Create(&newData)

HTH,
Yamil

I saw some GORM instructions that did something similar to this:

type NewData struct {
	gorm.Model
	Name string
	Date time.Time gorm:"what I do here?"
}

newData := &NewData{
	Name: "someName",
    // Date is expected to be stored in another table other
    // than NewData but with the same ID in NewData.
	Date: time.Now(),
}

// So, when executing this statement NewData only has the names column
// while Date is stored in the other table (History struct) that we have associated,
// the point is that I don't know how that is done.
db.Create(&newData)

You would need to add the historyID field to the NewData struct.
Check this line

newData := NewData { Bame : “Your Name”, HistoryID : history.ID }

type NewData  struct {
    gorm.Model
	Name string
    HistoryID uint64
}      

But that is 2 queries to the database, one to obtain history.ID and another to create newData. I want (if possible) only one direct query.

Solution:


type NewData struct {
	gorm.Model
	Name string
    // use ID as foreign key
    History History `gorm:"foreignKey:ID;constraint:OnUpdate:CASCADE,OnDelete:SET NULL"`
}

type History struct {
	ID uint
	Date time.Time
}

newData := &NewData{
    Name: "Julia",
    History: History{
        Date: time.Now(),
    },
}

// Two rows will be created in the NewData and History
// tables at the same time with the same ID.
db.Create(newData)