mirror of
https://github.com/gogf/gf.git
synced 2025-04-05 03:05:05 +08:00
fix(database/gdb): orm tag from embedded struct is missing in with
feature (#4011)
This commit is contained in:
parent
c9b0237fc7
commit
ba968949f7
@ -1457,3 +1457,102 @@ func Test_Issue3915(t *testing.T) {
|
||||
t.Assert(all[0]["id"], 2)
|
||||
})
|
||||
}
|
||||
|
||||
type RoleBase struct {
|
||||
gmeta.Meta `orm:"table:sys_role"`
|
||||
Name string `json:"name" description:"角色名称" `
|
||||
Code string `json:"code" description:"角色 code" `
|
||||
Description string `json:"description" description:"描述信息" `
|
||||
Weight int `json:"weight" description:"排序" `
|
||||
StatusId int `json:"statusId" description:"发布状态" `
|
||||
CreatedAt *gtime.Time `json:"createdAt" description:"" `
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" description:"" `
|
||||
}
|
||||
|
||||
type Role struct {
|
||||
gmeta.Meta `orm:"table:sys_role"`
|
||||
RoleBase
|
||||
Id uint `json:"id" description:""`
|
||||
Status *Status `json:"status" description:"发布状态" orm:"with:id=status_id" `
|
||||
}
|
||||
|
||||
type StatusBase struct {
|
||||
gmeta.Meta `orm:"table:sys_status"`
|
||||
En string `json:"en" description:"英文名称" `
|
||||
Cn string `json:"cn" description:"中文名称" `
|
||||
Weight int `json:"weight" description:"排序权重" `
|
||||
}
|
||||
|
||||
type Status struct {
|
||||
gmeta.Meta `orm:"table:sys_status"`
|
||||
StatusBase
|
||||
Id uint `json:"id" description:""`
|
||||
}
|
||||
|
||||
// https://github.com/gogf/gf/issues/2119
|
||||
func Test_Issue2119(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
tables := []string{
|
||||
"sys_role",
|
||||
"sys_status",
|
||||
}
|
||||
|
||||
defer dropTable(tables[0])
|
||||
defer dropTable(tables[1])
|
||||
_ = tables
|
||||
array := gstr.SplitAndTrim(gtest.DataContent(`issue2119.sql`), ";")
|
||||
for _, v := range array {
|
||||
_, err := db.Exec(ctx, v)
|
||||
t.AssertNil(err)
|
||||
}
|
||||
roles := make([]*Role, 0)
|
||||
err := db.Ctx(context.Background()).Model(&Role{}).WithAll().Scan(&roles)
|
||||
t.AssertNil(err)
|
||||
expectStatus := []*Status{
|
||||
{
|
||||
StatusBase: StatusBase{
|
||||
En: "undecided",
|
||||
Cn: "未决定",
|
||||
Weight: 800,
|
||||
},
|
||||
Id: 2,
|
||||
},
|
||||
{
|
||||
StatusBase: StatusBase{
|
||||
En: "on line",
|
||||
Cn: "上线",
|
||||
Weight: 900,
|
||||
},
|
||||
Id: 1,
|
||||
},
|
||||
{
|
||||
StatusBase: StatusBase{
|
||||
En: "on line",
|
||||
Cn: "上线",
|
||||
Weight: 900,
|
||||
},
|
||||
Id: 1,
|
||||
},
|
||||
{
|
||||
StatusBase: StatusBase{
|
||||
En: "on line",
|
||||
Cn: "上线",
|
||||
Weight: 900,
|
||||
},
|
||||
Id: 1,
|
||||
},
|
||||
{
|
||||
StatusBase: StatusBase{
|
||||
En: "on line",
|
||||
Cn: "上线",
|
||||
Weight: 900,
|
||||
},
|
||||
Id: 1,
|
||||
},
|
||||
}
|
||||
|
||||
for i := 0; i < len(roles); i++ {
|
||||
t.Assert(roles[i].Status, expectStatus[i])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
47
contrib/drivers/mysql/testdata/issue2119.sql
vendored
Normal file
47
contrib/drivers/mysql/testdata/issue2119.sql
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for sys_role
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `sys_role`;
|
||||
CREATE TABLE `sys_role` (
|
||||
`id` int(0) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '||s',
|
||||
`name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '角色名称||s,r',
|
||||
`code` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '角色 code||s,r',
|
||||
`description` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '描述信息|text',
|
||||
`weight` int(0) UNSIGNED NOT NULL DEFAULT 0 COMMENT '排序||r|min:0#发布状态不能小于 0',
|
||||
`status_id` int(0) UNSIGNED NOT NULL DEFAULT 1 COMMENT '发布状态|hasOne|f:status,fk:id',
|
||||
`created_at` datetime(0) NULL DEFAULT NULL,
|
||||
`updated_at` datetime(0) NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `code`(`code`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1091 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统角色表' ROW_FORMAT = Compact;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of sys_role
|
||||
-- ----------------------------
|
||||
INSERT INTO `sys_role` VALUES (1, '开发人员', 'developer', '123123', 900, 2, '2022-09-03 21:25:03', '2022-09-09 23:35:23');
|
||||
INSERT INTO `sys_role` VALUES (2, '管理员', 'admin', '', 800, 1, '2022-09-03 21:25:03', '2022-09-09 23:00:17');
|
||||
INSERT INTO `sys_role` VALUES (3, '运营', 'operator', '', 700, 1, '2022-09-03 21:25:03', '2022-09-03 21:25:03');
|
||||
INSERT INTO `sys_role` VALUES (4, '客服', 'service', '', 600, 1, '2022-09-03 21:25:03', '2022-09-03 21:25:03');
|
||||
INSERT INTO `sys_role` VALUES (5, '收银', 'account', '', 500, 1, '2022-09-03 21:25:03', '2022-09-03 21:25:03');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for sys_status
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `sys_status`;
|
||||
CREATE TABLE `sys_status` (
|
||||
`id` int(0) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`en` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '英文名称',
|
||||
`cn` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '中文名称',
|
||||
`weight` int(0) UNSIGNED NOT NULL DEFAULT 0 COMMENT '排序权重',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '发布状态' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of sys_status
|
||||
-- ----------------------------
|
||||
INSERT INTO `sys_status` VALUES (1, 'on line', '上线', 900);
|
||||
INSERT INTO `sys_status` VALUES (2, 'undecided', '未决定', 800);
|
||||
INSERT INTO `sys_status` VALUES (3, 'off line', '下线', 700);
|
@ -145,13 +145,17 @@ func (m *Model) doWithScanStruct(pointer interface{}) error {
|
||||
bindToReflectValue = bindToReflectValue.Addr()
|
||||
}
|
||||
|
||||
// It automatically retrieves struct field names from current attribute struct/slice.
|
||||
if structType, err := gstructs.StructType(field.Value); err != nil {
|
||||
if structFields, err := gstructs.Fields(gstructs.FieldsInput{
|
||||
Pointer: field.Value,
|
||||
RecursiveOption: gstructs.RecursiveOptionEmbeddedNoTag,
|
||||
}); err != nil {
|
||||
return err
|
||||
} else {
|
||||
fieldKeys = structType.FieldKeys()
|
||||
fieldKeys = make([]string, len(structFields))
|
||||
for i, field := range structFields {
|
||||
fieldKeys[i] = field.Name()
|
||||
}
|
||||
}
|
||||
|
||||
// Recursively with feature checks.
|
||||
model = m.db.With(field.Value).Hook(m.hookHandler)
|
||||
if m.withAll {
|
||||
@ -267,11 +271,16 @@ func (m *Model) doWithScanStructs(pointer interface{}) error {
|
||||
if gutil.IsEmpty(relatedTargetValue) {
|
||||
return nil
|
||||
}
|
||||
// It automatically retrieves struct field names from current attribute struct/slice.
|
||||
if structType, err := gstructs.StructType(field.Value); err != nil {
|
||||
if structFields, err := gstructs.Fields(gstructs.FieldsInput{
|
||||
Pointer: field.Value,
|
||||
RecursiveOption: gstructs.RecursiveOptionEmbeddedNoTag,
|
||||
}); err != nil {
|
||||
return err
|
||||
} else {
|
||||
fieldKeys = structType.FieldKeys()
|
||||
fieldKeys = make([]string, len(structFields))
|
||||
for i, field := range structFields {
|
||||
fieldKeys[i] = field.Name()
|
||||
}
|
||||
}
|
||||
// Recursively with feature checks.
|
||||
model = m.db.With(field.Value).Hook(m.hookHandler)
|
||||
|
Loading…
x
Reference in New Issue
Block a user