Home > database >  Why isn't the variable overwritten?
Why isn't the variable overwritten?

Time:12-27

If you write it this way

func showAll(db *gorm.DB) {
   users := &[]models.User{}
   card := models.Card{}
   db.Find(users)
   for _, i := range *users {
      fmt.Println(i)

      db.Where("user_id = ?", i.ID).Find(&card)
      fmt.Println(card)
   }
}

then fmt.Println(card) always prints the first value. But if you write it this way

func showAll(db *gorm.DB) {
   users := &[]models.User{}
   
   db.Find(users)
   for _, i := range *users {
      fmt.Println(i)
      card := models.Card{}
      db.Where("user_id = ?", i.ID).Find(&card)
      fmt.Println(card)
   }
}

It prints correctly. Why? Shouldn't the &card variable be overwritten?

I wanted to print all the cards for found users.

CodePudding user response:

Your first problem is that you aren't handling errors, if you were then you would know that all queries after the first one result in record-not-found. Second of your problems is the fact that you don't seem to be aware that gorm has debugging which, if you turn it on, will show the generated SQL and if you were to look at that you would immediately spot what's wrong. Finally, your actual problem, is the fact that after the first iteration the card struct instance has a non-zero ID which, alongside the explicit i.ID is also used in the WHERE clause.

So unless i.ID and card.ID are identical (or card.ID is zero) then:

db.Where("user_id = ?", i.ID).Find(&card).Error == ErrRecordNotFound

https://gorm.io/docs/query.html#String-Conditions

If the object’s primary key has been set, then condition query wouldn’t cover the value of primary key but use it as a ‘and’ condition. For example:

var user = User{ID: 10}
db.Where("id = ?", 20).First(&user)
// SELECT * FROM users WHERE id = 10 and id = 20 ORDER BY id ASC LIMIT 1

This query would give record not found Error. So set the primary key attribute such as id to nil before you want to use the variable such as user to get new value from database.

  • Related