Skip to content

Treat serializer-tagged fields as columns, not associations - #65

Open
dschreij wants to merge 2 commits into
go-gorm:masterfrom
dschreij:fix/serializer-columns
Open

dschreij wants to merge 2 commits into
go-gorm:masterfrom
dschreij:fix/serializer-columns

Conversation

@dschreij

@dschreij dschreij commented Sep 5, 2026

Copy link
Copy Markdown

Problem

A field with a serializer: tag (serializer:json, for one) is stored in a single column whatever its Go type. The generator classified such fields by their type: a struct became field.Struct, a slice field.Slice, so Set and Where on a serialized column produced association SQL.

Fix

hasSerializerTag reads the gorm tag, and a serialized field gets field.Field[T]. shortTypeName shortens the type expression while keeping its shape: []*example.com/pkg.T becomes []*pkg.T and map[string]example.com/pkg.T becomes map[string]pkg.T, where path.Base alone would drop the prefix.

Test

TestSerializedFieldsAreColumns generates over a struct with serialized struct, slice and map fields next to a real association and asserts each helper; TestShortTypeName covers the type expression shapes.

The first commit adds a small test helper (generateFromSources, containsField) that writes ad hoc sources into a throwaway module and runs the generator over them. The other pull requests from this fork share that commit; git merges the identical addition without conflict, so they can land in any order.

🤖 Generated with Claude Code

Copilot AI lite review requested due to automatic review settings September 5, 2026 07:52

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new tests and helper have a couple of concrete gaps (notably the stated map-coverage case and helper robustness) that should be addressed to match the PR’s intended guarantees.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR updates the internal code generator to treat GORM serializer:-tagged struct fields as single database columns (not associations), ensuring generated Set/Where helpers produce column SQL even when the Go type is a struct/slice/map-like type.

Changes:

  • Add hasSerializerTag to detect serializer: in gorm struct tags and classify those fields as field.Field[T].
  • Add shortTypeName to shorten full import paths inside type expressions while preserving shape (pointers/slices/maps/generics).
  • Add generator-focused tests plus a small helper to generate code from ad hoc sources.
File summaries
File Description
internal/gen/utils.go Adds serializer-tag detection and type-shortening helpers used by generation logic.
internal/gen/generator.go Updates Field.Type() to emit field.Field[...] for serializer-tagged fields (avoids association handling).
internal/gen/serializer_columns_test.go Adds regression tests asserting serializer-tagged fields generate column helpers, plus shortTypeName unit tests.
internal/gen/generator_support_test.go Adds a test utility to generate code from in-memory sources via a temp module.
Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +19 to +23
for name, content := range files {
if err := os.WriteFile(filepath.Join(dir, name), []byte(content), 0o644); err != nil {
t.Fatalf("write %s: %v", name, err)
}
}
Comment on lines +7 to +24
"model.go": "package sample\n\n" +
"type Attr struct {\n\tKey string\n\tValue string\n}\n\n" +
"type Meta struct {\n\tNote string\n}\n\n" +
"type Doc struct {\n" +
"\tID uint\n" +
"\tAttrs []Attr `gorm:\"serializer:json\"`\n" +
"\tMeta *Meta `gorm:\"type:jsonb;serializer:json\"`\n" +
"\tTags []string `gorm:\"serializer:json\"`\n" +
"\tLinks []Attr\n" +
"}\n",
})

for _, want := range [][2]string{
{"Attrs", "field.Field[[]sample.Attr]"},
{"Meta", "field.Field[sample.Meta]"},
{"Tags", "field.Field[[]string]"},
{"Links", "field.Slice[sample.Attr]"},
} {
@dschreij

dschreij commented Sep 5, 2026

Copy link
Copy Markdown
Author

Addressed the review. The shared test helper now creates parent directories before writing, so a nested key like models/model.go works as its doc comment promises.

Added the map case: a named map[string]string with the serializer tag now asserts field.Field[sample.Options], and the same type without the tag asserts field.Struct[sample.Options], so the tag is what the test attributes the change to.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The change is narrowly scoped, aligns with the stated behavior, and is covered by targeted tests that exercise the new serializer handling and type-shortening logic.

Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@dschreij
dschreij force-pushed the fix/serializer-columns branch from 53b2d4f to da89857 Compare September 5, 2026 20:00
@dschreij

dschreij commented Sep 5, 2026

Copy link
Copy Markdown
Author

Addressed the second round.

The shared test helper now reads the whole output tree rather than its top level, so a fixture that spans packages is not silently truncated. That was only reachable once the helper started accepting nested source paths, so thank you for following it through.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants