diff --git a/database/gdb/gdb_z_mysql_model_test.go b/database/gdb/gdb_z_mysql_model_test.go index dc1bdb510..153711135 100644 --- a/database/gdb/gdb_z_mysql_model_test.go +++ b/database/gdb/gdb_z_mysql_model_test.go @@ -4227,3 +4227,47 @@ func Test_Model_WherePrefixLike(t *testing.T) { t.Assert(r[0]["id"], "3") }) } + +// https://github.com/gogf/gf/issues/1700 +func Test_Model_Issue1700(t *testing.T) { + table := "user_" + gtime.Now().TimestampNanoStr() + if _, err := db.Exec(ctx, fmt.Sprintf(` + CREATE TABLE %s ( + id int(10) unsigned NOT NULL AUTO_INCREMENT, + user_id int(10) unsigned NOT NULL, + UserId int(10) unsigned NOT NULL, + PRIMARY KEY (id) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + `, table, + )); err != nil { + gtest.AssertNil(err) + } + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + type User struct { + Id int `orm:"id"` + Userid int `orm:"user_id"` + UserId int `orm:"UserId"` + } + _, err := db.Model(table).Data(User{ + Id: 1, + Userid: 2, + UserId: 3, + }).Insert() + t.AssertNil(err) + one, err := db.Model(table).One() + t.AssertNil(err) + t.Assert(one, g.Map{ + "id": 1, + "user_id": 2, + "UserId": 3, + }) + var user *User + err = db.Model(table).Scan(&user) + t.AssertNil(err) + t.Assert(user.Id, 1) + t.Assert(user.Userid, 2) + t.Assert(user.UserId, 3) + }) +} diff --git a/util/gconv/gconv_struct.go b/util/gconv/gconv_struct.go index b24d9d711..2de206c59 100644 --- a/util/gconv/gconv_struct.go +++ b/util/gconv/gconv_struct.go @@ -250,15 +250,8 @@ func doStruct(params interface{}, pointer interface{}, mapping map[string]string tagMap[attributeName] = utils.RemoveSymbols(strings.Split(tagName, ",")[0]) // If tag and attribute values both exist in `paramsMap`, // it then uses the tag value overwriting the attribute value in `paramsMap`. - if paramsMap[tagName] != nil { - for paramsKey, _ := range paramsMap { - if paramsKey == tagName { - continue - } - if utils.EqualFoldWithoutChars(paramsKey, attributeName) { - paramsMap[paramsKey] = paramsMap[tagName] - } - } + if paramsMap[tagName] != nil && paramsMap[attributeName] != nil { + paramsMap[attributeName] = paramsMap[tagName] } } @@ -276,18 +269,23 @@ func doStruct(params interface{}, pointer interface{}, mapping map[string]string } // It secondly checks the predefined tags and matching rules. if attrName == "" { - checkName = utils.RemoveSymbols(mapK) - // Loop to find the matched attribute name with or without - // string cases and chars like '-'/'_'/'.'/' '. + // It firstly considers `mapK` as accurate tag name, and retrieve attribute name from `tagToNameMap` . + attrName = tagToNameMap[mapK] + if attrName == "" { + checkName = utils.RemoveSymbols(mapK) + // Loop to find the matched attribute name with or without + // string cases and chars like '-'/'_'/'.'/' '. - // Matching the parameters to struct tag names. - // The `attrKey` is the attribute name of the struct. - for attrKey, cmpKey := range tagMap { - if strings.EqualFold(checkName, cmpKey) { - attrName = attrKey - break + // Matching the parameters to struct tag names. + // The `attrKey` is the attribute name of the struct. + for attrKey, cmpKey := range tagMap { + if strings.EqualFold(checkName, cmpKey) { + attrName = attrKey + break + } } } + // Matching the parameters to struct attributes. if attrName == "" { for attrKey, cmpKey := range attrMap {