Skip to content

fix(seedling-gen): Generate usable defaults for conventional GORM models - #101

Merged
mhiro2 merged 4 commits into
mainfrom
fix/gorm-generated-defaults
Oct 13, 2026
Merged

mhiro2 merged 4 commits into
mainfrom
fix/gorm-generated-defaults

Conversation

@mhiro2

@mhiro2 mhiro2 commented Oct 13, 2026

Copy link
Copy Markdown
Owner

Summary

  • Leave GORM's inferred untagged ID primary key to the database so repeated inserts no longer collide on ID: 1
  • Generate compilable defaults for models embedding gorm.Model by nesting promoted fields under the embedded struct
  • Add the time import only when the generated code actually references it
  • Cover conventional hand-written GORM models with a SQLite lifecycle fixture that performs repeated and batch inserts

Changes

  • 39f86e8 : fix(seedling-gen): leave inferred GORM primary keys out of defaults
    • Defaults now exclude every key field the blueprint registers, including the ID field GORM treats as the primary key when no field carries a primaryKey tag
  • d488f11 : fix(seedling-gen): nest gorm.Model defaults under the embedded struct
    • The normalized IR records the embedded struct that promotes each field, and the defaults literal groups those assignments as Model: gorm.Model{...} instead of invalid top-level promoted keys
    • A hand-written fixture with an untagged ID and an embedded gorm.Model is migrated into SQLite and exercised with repeated inserts, batch inserts, and cleanup
  • 8a32d46 : fix(seedling-gen): import time only when generated code references it
    • The shared renderer decides the import: emitted struct field types count only for the SQL and Atlas adapters, and otherwise only a rendered time.Time default does
    • A model whose only time.Time field is a key now compiles instead of failing with an unused import
  • 0621d67 : docs(seedling-gen): describe key inference and embedded gorm.Model defaults
    • The guide, ARCHITECTURE.md, and the seedling-gen skill describe the inferred key handling, embedded gorm.Model defaults, and conditional time import

When no field carries a primaryKey tag, GORM treats the field named ID
as the primary key, and the generator already registered it as the
blueprint key. The defaults still saw the field as an ordinary uint
and set it to 1, so every insert after the first failed with a unique
constraint violation. The defaults now exclude every key field the
blueprint registers, whether tagged or inferred.
Models embedding gorm.Model had their promoted CreatedAt and UpdatedAt
defaults written as top-level keys of the model literal, which Go
rejects for promoted fields, so the generated file did not compile.
The normalized IR now records the embedded struct that promotes each
field, and the defaults literal groups those assignments under it as
Model: gorm.Model{...}. A hand-written fixture with an untagged ID and
an embedded gorm.Model runs repeated and batch inserts against SQLite.
Each adapter added the time import whenever any model field had type
time.Time, even when that field was a key or relation field the
defaults skip, so a model whose only time.Time field was its primary
key generated code that failed with "time" imported and not used. The
shared renderer now decides the import itself: emitted struct field
types count only for the SQL and Atlas adapters that write structs,
and otherwise only a rendered time default does.
…faults

Note that generated defaults skip GORM's untagged ID key, write fields
promoted from gorm.Model through the embedded struct literal, and add
the time import only when generated code uses it.
@mhiro2 mhiro2 self-assigned this Oct 13, 2026
@mhiro2 mhiro2 added the bug Something isn't working label Oct 13, 2026
@github-actions

Copy link
Copy Markdown

Code Metrics Report

main (4880ed2) #101 (d5a0588) +/-
Coverage 86.7% 86.8% +0.1%
Code to Test Ratio 1:0.9 1:1.0 +0.0
Test Execution Time 48s 1m18s +30s
Details
  |                     | main (4880ed2) | #101 (d5a0588) |  +/-  |
  |---------------------|----------------|----------------|-------|
+ | Coverage            |          86.7% |          86.8% | +0.1% |
  |   Files             |             59 |             59 |     0 |
  |   Lines             |           4771 |           4790 |   +19 |
+ |   Covered           |           4139 |           4161 |   +22 |
+ | Code to Test Ratio  |          1:0.9 |          1:1.0 |  +0.0 |
  |   Code              |          17736 |          17783 |   +47 |
+ |   Test              |          17596 |          17797 |  +201 |
- | Test Execution Time |            48s |          1m18s |  +30s |

Code coverage of files in pull request scope (87.6% → 88.1%, patch 96.4%)

Files Coverage +/- Patch Coverage Status
cmd/seedling-gen/ent.go 81.4% -0.2% - modified
cmd/seedling-gen/generator.go 86.6% -0.9% - modified
cmd/seedling-gen/gorm.go 89.1% +1.2% 100.0% modified
cmd/seedling-gen/normalized_ir.go 90.9% +0.5% 96.0% modified

Reported by octocov

@mhiro2
mhiro2 merged commit 24ea819 into main Oct 13, 2026
11 checks passed
@mhiro2
mhiro2 deleted the fix/gorm-generated-defaults branch October 13, 2026 13:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant