Your Question

save()需要条件,默认不是使用id作为查询条件,没有就创建吗?Model不应该是选择模型/表,不参与查询吗?

实例代码

var user model.User
db := gorm.DB.Model(&model.User{}).WithContext(ctx)
if result := db.Where(&model.User{Id:1}).First(&user); result.RowsAffected == 1 {
        user.num++
}
// 如果这里使用gorm.DB的话没问题,但是本人偏向于gorm.DB.Model(&model.User{}).WithContext(ctx)方式,所以是这属于bug?
// 还是使用不当?
if err := db.Save(&user).Error;err != nil{
     panic(err)   //  这里会报错
}

Comment From: XiaoK29

db.Save(&user).Error 后面要加Error才会提交事务

提问忘记加.Error,而且这不是事务,你可以运行该代码,报错是WHERE conditions required,没有where条件

Comment From: black-06

https://github.com/go-gorm/gorm/blob/877cc9148f95552f51891d45d588af799033ceb8/callbacks/update.go#L15-L16. If you use DB.Model(&User{}).Save(&user), db.Statement.Model is &User{}, db.Statement.Dest is &user, so db.Statement.Model != db.Statement.Dest and ReflectValue get value from db.Statement.Mode https://github.com/go-gorm/gorm/blob/877cc9148f95552f51891d45d588af799033ceb8/callbacks/update.go#L183-L185 The WHERE conditions is build from ReflectValue so it's empty.

It's probably not a bug but a feature about Association.(I'm not sure). So I suggest you use DB.Save(&user) instead of DB.Model(&User{}).Save(&user)

Comment From: XiaoK29

https://github.com/go-gorm/gorm/blob/877cc9148f95552f51891d45d588af799033ceb8/callbacks/update.go#L15-L16

. If you use DB.Model(&User{}).Save(&user), db.Statement.Model is &User{}, db.Statement.Dest is &user, so db.Statement.Model != db.Statement.Dest and ReflectValue get value from db.Statement.Mode https://github.com/go-gorm/gorm/blob/877cc9148f95552f51891d45d588af799033ceb8/callbacks/update.go#L183-L185

The WHERE conditions is build from ReflectValue so it's empty. It's probably not a bug but a feature about Association.(I'm not sure). So I suggest you use DB.Save(&user) instead of DB.Model(&User{}).Save(&user)

使用DB.Save(&user)的确没有问题,但是本人更偏向于DB.Model(&model.User{}).Save(&user)写法,所以这个算bug还是?因为Model不应该是选择模型/表,不参与查询吗?

Comment From: black-06

Probably not a bug, see this test case. https://github.com/go-gorm/gorm/blob/877cc9148f95552f51891d45d588af799033ceb8/tests/update_test.go#L543-L557

Comment From: black-06

Maybe we should document this

Comment From: XiaoK29

Probably not a bug, see this test case.

https://github.com/go-gorm/gorm/blob/877cc9148f95552f51891d45d588af799033ceb8/tests/update_test.go#L543-L557

我一直把Model()当Table()使用,也许不应该这样使用吧

Comment From: a631807682

Maybe we should document this

Are you interested in creating a PR for it?

Comment From: black-06

Maybe we should document this

Are you interested in creating a PR for it?

It's a little confusing here.

// UPDATE `users` SET `name`="jinzhu" WHERE `id` = 1
db.Save(&User{ID: 1, Name: "jinzhu"})

// INSERT INTO `users` (`name`) VALUES ("jinzhu")
db.Save(&User{Name: "jinzhu"})

// UPDATE `users` SET `name`="jinzhu" WHERE `id` = 1
db.Model(&User{ID: 1}).Save(&User{ID: 1, Name: "jinzhu"})

// INSERT INTO `users` (`name`) VALUES ("jinzhu")
db.Model(&User{ID: 1}).Save(&User{Name: "jinzhu"}) // but dest primary key is nil,  insert

Maybe we should discuss what kind of behavior is right...

Comment From: XiaoK29

Maybe we should document this

Are you interested in creating a PR for it?

It's a little confusing here.

``go // UPDATEusersSETname="jinzhu" WHEREid` = 1 db.Save(&User{ID: 1, Name: "jinzhu"})

// INSERT INTO users (name) VALUES ("jinzhu") db.Save(&User{Name: "jinzhu"})

// UPDATE users SET name="jinzhu" WHERE id = 1 db.Model(&User{ID: 1}).Save(&User{ID: 1, Name: "jinzhu"})

// INSERT INTO users (name) VALUES ("jinzhu") db.Model(&User{ID: 1}).Save(&User{Name: "jinzhu"}) // but dest primary key is nil, insert ```

Maybe we should discuss what kind of behavior is right...

确实,gorm的写法太多了

Comment From: a631807682

Maybe we should document this

Are you interested in creating a PR for it?

It's a little confusing here.

``go // UPDATEusersSETname="jinzhu" WHEREid` = 1 db.Save(&User{ID: 1, Name: "jinzhu"})

// INSERT INTO users (name) VALUES ("jinzhu") db.Save(&User{Name: "jinzhu"})

// UPDATE users SET name="jinzhu" WHERE id = 1 db.Model(&User{ID: 1}).Save(&User{ID: 1, Name: "jinzhu"})

// INSERT INTO users (name) VALUES ("jinzhu") db.Model(&User{ID: 1}).Save(&User{Name: "jinzhu"}) // but dest primary key is nil, insert ```

Maybe we should discuss what kind of behavior is right...

When save value does not contain primary key, it will automatically execute Create. It cannot be used with Model. Model is mainly used to specify table and where conditions, but save is a combination function, it will be difficult to understand if you add where conditions to the insert statement, so I think there are reasons why model is not allowed.

Of course, the above does not discuss the different structures of model and dest, just like create or update, so this may be a feature, but before implementing it, we may need to remind users through documentation.

https://github.com/go-gorm/gorm/blob/master/finisher_api.go#L88

Comment From: MQPearth

Maybe we should document this

Are you interested in creating a PR for it?

It's a little confusing here. ``go // UPDATEusersSETname="jinzhu" WHEREid` = 1 db.Save(&User{ID: 1, Name: "jinzhu"})

// INSERT INTO users (name) VALUES ("jinzhu") db.Save(&User{Name: "jinzhu"})

// UPDATE users SET name="jinzhu" WHERE id = 1 db.Model(&User{ID: 1}).Save(&User{ID: 1, Name: "jinzhu"})

// INSERT INTO users (name) VALUES ("jinzhu") db.Model(&User{ID: 1}).Save(&User{Name: "jinzhu"}) // but dest primary key is nil, insert ```

Maybe we should discuss what kind of behavior is right...

确实,gorm的写法太多了

api设计混乱