fix(09): WR-16 resolve model columns through embedded structs and explicit column tags

This commit is contained in:
Jakub Zych
2026-10-01 21:31:46 +02:00
parent 2d96adf775
commit 629fac4d29
9 changed files with 229 additions and 54 deletions

View File

@@ -842,21 +842,38 @@ func projectRow(row any, controller pact.AdminController, cols []ListColumn) map
return out
}
// fieldByColumn returns the model field stored in column, looking through
// embedded structs such as gorm.Model. A field with an explicit `column:` tag is
// matched by that tag alone; only an untagged field falls back to its Go name
// (case-insensitive) or GORM's default column name for it, and a shallower
// field shadows an embedded one, as in Go.
func fieldByColumn(v reflect.Value, column string) reflect.Value {
if v.Kind() != reflect.Struct {
return reflect.Value{}
}
t := v.Type()
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
if field.PkgPath != "" {
continue
}
if gormColumn(field) == column || strings.EqualFold(field.Name, column) {
return v.Field(i)
fields := modelFields(v.Type())
best := -1
for i := range fields {
if gormColumn(fields[i].Field) == column && (best < 0 || len(fields[i].Path) < len(fields[best].Path)) {
best = i
}
}
return reflect.Value{}
if best < 0 {
for i := range fields {
untagged := gormColumn(fields[i].Field) == ""
if untagged && (strings.EqualFold(fields[i].Field.Name, column) || defaultColumnName(fields[i].Field) == column) && (best < 0 || len(fields[i].Path) < len(fields[best].Path)) {
best = i
}
}
}
if best < 0 {
return reflect.Value{}
}
field, err := v.FieldByIndexErr(fields[best].Path)
if err != nil {
return reflect.Value{}
}
return field
}
func gormColumn(field reflect.StructField) string {