Skip to content

Conversation

@uptutu
Copy link
Contributor

@uptutu uptutu commented Sep 15, 2025

#15


Enhanced Code Generation for Pointer-Embedded gorm.Model and Base Field Inclusion

This pull request implements comprehensive enhancements to the code generation system, enabling proper support for both pointer-embedded (*gorm.Model) and value-embedded (gorm.Model) struct bases within user models. The PR refactors core embedding logic in internal/gen/generator.go for generalized, modular field processing, adds caching of the Go module directory to optimize filesystem access, updates field type handling for improved nullable field support, expands the .gitignore file to follow best practices, and introduces new example/test coverage for pointer embedding scenarios (e.g., the new CreditCard example). These changes collectively resolve issue #15 and strengthen the code generator's flexibility, correctness, and maintainability for complex model patterns.

Key Changes

• Refactored handleAnonymousEmbedding in internal/gen/generator.go for generalized support of pointer and value struct embedding, with explicit pointer unwrapping and modular helper functions (addEmbeddedFields, loadAndProcessExternalStruct).
• Introduced a cached goModDir attribute on the File struct to minimize repeated calls to findGoModDir(), reducing filesystem access overhead.
• Updated field type mapping logic to properly use field.Field[sql.NullTime], field.Field[sql.NullInt64], and improved nullable field detection.
• Significantly expanded .gitignore to cover build, editor, OS, sensitive, and generated file patterns; removed duplications.
• Added new CreditCard model example embedding *gorm.Model, corresponding generated output, and expanded tests in examples/output/models_field_helpers_test.go to verify pointer embedding and base field handling.

Affected Areas

internal/gen/generator.go (embedding/reflection/refactoring, caching)
examples/models/user.go (added CreditCard model with *gorm.Model pointer embedding)
examples/output/models/user.go (generated code updated for new model/fields)
examples/output/models_field_helpers_test.go (expanded test assertions for new model/fields)
.gitignore (expanded and deduplicated coverage)


This summary was automatically generated by @propel-code-bot

Copilot AI review requested due to automatic review settings September 15, 2025 10:05
@propel-code-bot propel-code-bot bot changed the title fix 模型使用了 *gorm.Model 作为字段内嵌再解析生成的文件中会缺失对应的 gorm.Model 中的字段 Fix generation of embedded *gorm.Model fields to include base fields Sep 15, 2025
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR fixes an issue where models using *gorm.Model as an embedded field were missing the corresponding gorm.Model fields in the generated files. The fix improves the handling of anonymous embedded fields, particularly for pointer types to external structs.

  • Refactored the handleAnonymousEmbedding function to properly handle pointer-wrapped embedded types
  • Added helper functions to streamline the processing of embedded struct fields
  • Fixed field type handling to unwrap pointer types before processing embedded structs

Reviewed Changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 2 comments.

File Description
internal/gen/generator.go Enhanced anonymous embedding handling to support pointer types and refactored code structure
examples/output/models/user.go Updated generated model to include gorm.Model fields and correct field types
examples/models/user.go Changed from gorm.Model to *gorm.Model to test pointer embedding

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines 741 to 747
loadAndProcessExternalStruct := func(pkgName, typeName string) bool {
st, err := loadNamedStructType(findGoModDir(p.inputPath), p.getFullImportPath(pkgName), typeName)
if err != nil || st == nil {
return false
}
return addEmbeddedFields(st, typeName, pkgName)
}
Copy link

Copilot AI Sep 15, 2025

Choose a reason for hiding this comment

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

The loadAndProcessExternalStruct function calls findGoModDir(p.inputPath) on every invocation. Consider caching this value at the struct level or passing it as a parameter to avoid repeated filesystem operations.

Copilot uses AI. Check for mistakes.
@propel-code-bot propel-code-bot bot changed the title Fix generation of embedded *gorm.Model fields to include base fields Fix code generation to support pointer embedding of gorm.Model and include base fields Sep 15, 2025
$GOCACHE/

# Air live reload
tmp/

Choose a reason for hiding this comment

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

[NitPick]

Duplicate tmp/ entry on lines 68 and 78. The Air live reload entry is redundant since temporary folders are already ignored above.

Context for Agents
[**NitPick**]

Duplicate `tmp/` entry on lines 68 and 78. The Air live reload entry is redundant since temporary folders are already ignored above.

File: .gitignore
Line: 78

@uptutu
Copy link
Contributor Author

uptutu commented Sep 16, 2025

Error: output/models_field_helpers_test.go:354:35: cannot use generated.User.Profile (variable of struct type "gorm.io/cli/gorm/field".String) as examples.JSON value in variable declaration

Hi @jinzhu

这个问题我需要一点时间看看,因为 example.JSON 不在 field 包内,应该算是一个实验字段或自定义字段, 当前我的想法是在 user 模型 tag 注释中添加更多内容让 gen 生成找到该符合规范的自定义字段然后使用。但是需要一点时间看看。可能才分成两个 PR 会更好一点。当前 PR 解决 *gorm.Model 问题

@uptutu
Copy link
Contributor Author

uptutu commented Sep 16, 2025

我看见了文档 json maping field 的用法,稍后我修复试一试

@jinzhu jinzhu requested a review from Copilot September 17, 2025 11:58
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 4 out of 5 changed files in this pull request and generated 2 comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

applicableConfigs []*genconfig.Config
inputPath string
relPath string
goModDir string // 缓存的 go mod 目录路径
Copy link

Copilot AI Sep 17, 2025

Choose a reason for hiding this comment

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

The comment contains Chinese characters. Please use English for consistency: // Cached go mod directory path

Suggested change
goModDir string // 缓存的 go mod 目录路径
goModDir string // Cached go mod directory path

Copilot uses AI. Check for mistakes.
Package: f.Name.Name,
inputPath: inputFile,
relPath: relPath,
goModDir: findGoModDir(inputFile), // 初始化时缓存 go mod 目录
Copy link

Copilot AI Sep 17, 2025

Choose a reason for hiding this comment

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

The comment contains Chinese characters. Please use English for consistency: // Initialize and cache go mod directory

Suggested change
goModDir: findGoModDir(inputFile), // 初始化时缓存 go mod 目录
goModDir: findGoModDir(inputFile), // Initialize and cache go mod directory

Copilot uses AI. Check for mistakes.
@jinzhu jinzhu requested a review from Copilot September 17, 2025 12:00
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 4 out of 5 changed files in this pull request and generated 2 comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +735 to +740
// Helper function to add fields from embedded struct
addEmbeddedFields := func(structType *ast.StructType, typeName, embeddedPkgName string) bool {
sub := p.processStructType(&ast.TypeSpec{Name: &ast.Ident{Name: typeName}}, structType, embeddedPkgName)
s.Fields = append(s.Fields, sub.Fields...)
return true
}
Copy link

Copilot AI Sep 17, 2025

Choose a reason for hiding this comment

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

The addEmbeddedFields helper function always returns true, making the return value meaningless. Consider either removing the return value or implementing proper error handling that could return false in failure cases.

Copilot uses AI. Check for mistakes.
Comment on lines +742 to +749
// Helper function to load and process external struct type
loadAndProcessExternalStruct := func(pkgName, typeName string) bool {
st, err := loadNamedStructType(p.goModDir, p.getFullImportPath(pkgName), typeName)
if err != nil || st == nil {
return false
}
return addEmbeddedFields(st, typeName, pkgName)
}
Copy link

Copilot AI Sep 17, 2025

Choose a reason for hiding this comment

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

The error from loadNamedStructType is silently ignored. Consider logging the error or propagating it to help with debugging when struct loading fails.

Copilot uses AI. Check for mistakes.
@jinzhu jinzhu merged commit 1a7be25 into go-gorm:master Sep 17, 2025
1 check passed
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