diff --git a/database/gdb/gdb_model_select.go b/database/gdb/gdb_model_select.go index eefbec99b..6aa22b88d 100644 --- a/database/gdb/gdb_model_select.go +++ b/database/gdb/gdb_model_select.go @@ -226,7 +226,11 @@ func (m *Model) doStruct(pointer interface{}, where ...interface{}) error { model := m // Auto selecting fields by struct attributes. if model.fieldsEx == "" && (model.fields == "" || model.fields == "*") { - model = m.Fields(pointer) + if v, ok := pointer.(reflect.Value); ok { + model = m.Fields(v.Interface()) + } else { + model = m.Fields(pointer) + } } one, err := model.One(where...) if err != nil { @@ -267,11 +271,19 @@ func (m *Model) doStructs(pointer interface{}, where ...interface{}) error { model := m // Auto selecting fields by struct attributes. if model.fieldsEx == "" && (model.fields == "" || model.fields == "*") { - model = m.Fields( - reflect.New( - reflect.ValueOf(pointer).Elem().Type().Elem(), - ).Interface(), - ) + if v, ok := pointer.(reflect.Value); ok { + model = m.Fields( + reflect.New( + v.Type().Elem(), + ).Interface(), + ) + } else { + model = m.Fields( + reflect.New( + reflect.ValueOf(pointer).Elem().Type().Elem(), + ).Interface(), + ) + } } all, err := model.All(where...) if err != nil { @@ -323,7 +335,6 @@ func (m *Model) Scan(pointer interface{}, where ...interface{}) error { reflectValue = reflectValue.Elem() reflectKind = reflectValue.Kind() } - switch reflectKind { case reflect.Slice, reflect.Array: return m.doStructs(pointer, where...) diff --git a/database/gdb/gdb_model_with.go b/database/gdb/gdb_model_with.go index 36782fffc..014df31a5 100644 --- a/database/gdb/gdb_model_with.go +++ b/database/gdb/gdb_model_with.go @@ -155,12 +155,10 @@ func (m *Model) doWithScanStruct(pointer interface{}) error { if parsedTagOutput.Order != "" { model = model.Order(parsedTagOutput.Order) } - err = model.Fields(fieldKeys).Where(relatedSourceName, relatedTargetValue).Scan(bindToReflectValue) if err != nil { return err } - } return nil } diff --git a/database/gdb/gdb_z_mysql_association_with_test.go b/database/gdb/gdb_z_mysql_association_with_test.go index 7345221d1..aef619da9 100644 --- a/database/gdb/gdb_z_mysql_association_with_test.go +++ b/database/gdb/gdb_z_mysql_association_with_test.go @@ -1991,3 +1991,44 @@ PRIMARY KEY (id) t.Assert(user.UserScores[4].Score, 5) }) } + +func Test_With_Feature_Issue1401(t *testing.T) { + var ( + table1 = "parcels" + table2 = "parcel_items" + ) + array := gstr.SplitAndTrim(gtest.TestDataContent(`issue1401.sql`), ";") + for _, v := range array { + if _, err := db.Exec(v); err != nil { + gtest.Error(err) + } + } + defer dropTable(table1) + defer dropTable(table2) + + gtest.C(t, func(t *gtest.T) { + type NItem struct { + Id int `json:"id"` + ParcelId int `json:"parcel_id"` + } + + type ParcelItem struct { + gmeta.Meta `orm:"table:parcel_items"` + NItem + } + + type ParcelRsp struct { + gmeta.Meta `orm:"table:parcels"` + Id int `json:"id"` + Items []*ParcelItem `json:"items" orm:"with:parcel_id=Id"` + } + + parcelDetail := &ParcelRsp{} + err := db.Model(table1).With(parcelDetail.Items).Where("id", 3).Scan(&parcelDetail) + t.AssertNil(err) + t.Assert(parcelDetail.Id, 3) + t.Assert(len(parcelDetail.Items), 1) + t.Assert(parcelDetail.Items[0].Id, 2) + t.Assert(parcelDetail.Items[0].ParcelId, 3) + }) +} diff --git a/database/gdb/testdata/issue1401.sql b/database/gdb/testdata/issue1401.sql new file mode 100644 index 000000000..b09087326 --- /dev/null +++ b/database/gdb/testdata/issue1401.sql @@ -0,0 +1,32 @@ +-- ---------------------------- +-- Table structure for parcel_items +-- ---------------------------- +DROP TABLE IF EXISTS `parcel_items`; +CREATE TABLE `parcel_items` ( + `id` int(11) NOT NULL, + `parcel_id` int(11) NULL DEFAULT NULL, + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of parcel_items +-- ---------------------------- +INSERT INTO `parcel_items` VALUES (1, 1, '新品'); +INSERT INTO `parcel_items` VALUES (2, 3, '新品2'); + +-- ---------------------------- +-- Table structure for parcels +-- ---------------------------- +DROP TABLE IF EXISTS `parcels`; +CREATE TABLE `parcels` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of parcels +-- ---------------------------- +INSERT INTO `parcels` VALUES (1); +INSERT INTO `parcels` VALUES (2); +INSERT INTO `parcels` VALUES (3); \ No newline at end of file