Skip to content

Conversation

@ComingCL
Copy link

@ComingCL ComingCL commented Oct 27, 2025

  • Do only one thing
  • Non breaking API changes
  • Tested

What did this pull request do?

This PR introduces the WithAutoRegistry option to automatically generate model registration code, eliminating the need for manual model registration boilerplate. The implementation includes:

Core Features:

  • Added WithAutoRegistry() method for automatic registration of all generated models
  • Added WithAutoRegistry(tables...) method for selective table registration
  • Generated init() functions in model files that automatically call RegisterModel()
  • Created centralized model registry system with thread-safe operations

Registry System:

  • RegisterModel(model, name) - Register a model instance with its name
  • GetAllModels() - Retrieve all registered model instances
  • GetAllModelNames() - Retrieve all registered model names
  • Removed redundant GetModelCount() and Clear() methods for cleaner API

Code Generation Improvements:

  • Enhanced model template to include conditional auto-registration
  • Improved registry template with simplified, focused functionality
  • Fixed import path issues in examples for better compatibility
  • Updated SQLite compatibility in test examples

Testing & Documentation:

  • Added comprehensive test suite (TestAutoRegistryInitGeneration)
  • Created example projects demonstrating usage patterns
  • Fixed existing test failures and improved test reliability

User Case Description

Problem:
In large projects with many database tables, developers need to manually register each generated model for reflection-based operations, dynamic queries, or runtime model discovery. This creates repetitive boilerplate code and increases maintenance overhead.

Before (Manual Registration):

// After generation, developers had to manually write:
func init() {
    registry.RegisterModel(&User{}, "User")
    registry.RegisterModel(&Order{}, "Order")
    registry.RegisterModel(&Product{}, "Product")
    // ... for every model
}

After (Automatic Registration):

// Simply enable auto-registration during generation:
g := gen.NewGenerator(gen.Config{
    OutPath: "./query",
    ModelPkgPath: "./model", 
})
g.WithAutoRegistry() // Auto-register all models
// or
g.WithAutoRegistry("users", "orders") // Selective registration

g.UseDB(db)
g.GenerateAllTable()
g.Execute()

// Generated models automatically include registration:
// user.gen.go
func init() {
    RegisterModel(&User{}, TableNameUser)
}

@propel-code-bot
Copy link

propel-code-bot bot commented Oct 27, 2025

Add WithAutoRegistry Code-Generation Mode (automatic model registration)

This PR introduces a fully-automated model-registry feature for GORM-Gen. By enabling the new WithAutoRegistry mode (optionally with a table allow-list), the generator now:
• Injects init() stubs into every generated model that call RegisterModel(&Model{}, TableNameModel).
• Emits a package-scoped, thread-safe registry (gen.go) containing RegisterModel, GetAllModels, and GetAllModelNames.
• Extends the code-generator core to emit the registry file, set per-table flags, and honour opt-in table filtering.
Extensive example updates, Go-module bumps, template changes, and a full test-suite (auto_registry_test.go) accompany the feature.

Key Changes

• 新增顶层配置方法 Config.WithAutoRegistry(tableNames ...string) 并在 generator.go 中实现整条生成流程
• 在 internal/template/model.go 中加入条件模板片段生成 init() 自动注册代码
• 新增模板 internal/template/registry.go 生成线程安全的模型注册表 (包含 RegisterModel, GetAllModels, GetAllModelNames)
• 核心生成器 (generator.go):在模型生成完成后输出 gen.go 注册文件,并在模型元数据上打 WithAutoRegistry 标识
• 配置结构体 (config.go) 扩展:增加 WithAutoRegistry 常量、RegistryTableList 字段及链式配置函数
• 模型解析结构体 (internal/generate/query.go) 扩展字段 WithAutoRegistry
• 大幅更新示例工程(SQLite 默认)及 go.mod/go.sum 依赖升级;修复 strings.Title 弃用问题(改用 cases.Title
• 新增综合测试 auto_registry_test.go 覆盖全路径(全部表、部分表、过滤表、配置接口等)

Affected Areas

generator.go (model generation pipeline, registry file emission)
config.go (public API surface)
internal/template/*.go (model & registry templates)
internal/generate/query.go (metadata flag)
• Examples & test-suite
• Go module dependencies

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

Comment on lines 159 to 168
// getExpectedModelName 根据表名获取期望的模型名
func getExpectedModelName(tableName string) string {
switch tableName {
case "users":
return "User"
case "orders":
return "Order"
default:
// 简单的首字母大写
return strings.Title(tableName)

Choose a reason for hiding this comment

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

[BestPractice]

Deprecated function usage detected: strings.Title is deprecated since Go 1.18. Use cases.Title from golang.org/x/text/cases package instead:

Suggested Change
Suggested change
// getExpectedModelName 根据表名获取期望的模型名
func getExpectedModelName(tableName string) string {
switch tableName {
case "users":
return "User"
case "orders":
return "Order"
default:
// 简单的首字母大写
return strings.Title(tableName)
func getExpectedModelName(tableName string) string {
switch tableName {
case "users":
return "User"
case "orders":
return "Order"
default:
// Convert first letter to uppercase
if len(tableName) == 0 {
return ""
}
return strings.ToUpper(tableName[:1]) + tableName[1:]
}
}

Committable suggestion

Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Context for Agents
[**BestPractice**]

Deprecated function usage detected: `strings.Title` is deprecated since Go 1.18. Use `cases.Title` from golang.org/x/text/cases package instead:

<details>
<summary>Suggested Change</summary>

```suggestion
func getExpectedModelName(tableName string) string {
	switch tableName {
	case "users":
		return "User"
	case "orders":
		return "Order"
	default:
		// Convert first letter to uppercase
		if len(tableName) == 0 {
			return ""
		}
		return strings.ToUpper(tableName[:1]) + tableName[1:]
	}
}
```

⚡ **Committable suggestion**

Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

</details>

File: auto_registry_test.go
Line: 168

Comment on lines 274 to 278
for i, expected := range tt.expectedList {
if i >= len(cfg.RegistryTableList) || cfg.RegistryTableList[i] != expected {
t.Errorf("RegistryTableList[%d] = %s, want %s",
i, cfg.RegistryTableList[i], expected)
}

Choose a reason for hiding this comment

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

[BestPractice]

Potential slice bounds error: Accessing cfg.RegistryTableList[i] in the error message without verifying i < len(cfg.RegistryTableList) could panic if the slice is shorter than expected:

Suggested Change
Suggested change
for i, expected := range tt.expectedList {
if i >= len(cfg.RegistryTableList) || cfg.RegistryTableList[i] != expected {
t.Errorf("RegistryTableList[%d] = %s, want %s",
i, cfg.RegistryTableList[i], expected)
}
for i, expected := range tt.expectedList {
if i >= len(cfg.RegistryTableList) {
t.Errorf("RegistryTableList[%d] missing, want %s", i, expected)
} else if cfg.RegistryTableList[i] != expected {
t.Errorf("RegistryTableList[%d] = %s, want %s",
i, cfg.RegistryTableList[i], expected)
}
}

Committable suggestion

Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Context for Agents
[**BestPractice**]

Potential slice bounds error: Accessing `cfg.RegistryTableList[i]` in the error message without verifying `i < len(cfg.RegistryTableList)` could panic if the slice is shorter than expected:

<details>
<summary>Suggested Change</summary>

```suggestion
			for i, expected := range tt.expectedList {
				if i >= len(cfg.RegistryTableList) {
					t.Errorf("RegistryTableList[%d] missing, want %s", i, expected)
				} else if cfg.RegistryTableList[i] != expected {
					t.Errorf("RegistryTableList[%d] = %s, want %s",
						i, cfg.RegistryTableList[i], expected)
				}
			}
```

⚡ **Committable suggestion**

Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

</details>

File: auto_registry_test.go
Line: 278

Copy link

@propel-code-bot propel-code-bot bot left a comment

Choose a reason for hiding this comment

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

LGTM, ship it! 🚢


Why was this auto-approved?
AI analysis completed with no actionable comments or suggestions.

@ComingCL
Copy link
Author

Hi @jinzhu @miseyu @zaneli @clouds56 could you please review this PR when you have time ? I'd particularly appreciate your feedback on it. Thank you! 🙏

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.

1 participant