关于 generators
面向 Rails 开发者和编码 Agent 的生成器使用指南,涵盖选择、配置和安全运行生成器。重点是只创建所需文件,并先检查项目默认值、预览变更或撤销生成结果。
主要功能
- 01选择最具体的内置生成器
- 02检查项目生成器默认配置
- 03用 --pretend 预览文件变更
- 04用 bin/rails destroy 撤销生成
- 05创建自定义生成器和模板
适用场景
- 01只生成模型而不创建 scaffold 文件
- 02创建前预览多文件 scaffold
- 03配置 UUID 和 helper 生成默认值
- 04构建可复用的项目专用生成器
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ thinkoodle/ rails-skills --skill generators安装后在 Claude Code 中输入/generators确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/built-in-generators.mdcustom-generators.mdtemplates.mdtesting.mdthor-actions.md详细介绍
Rails 生成器专家
使用合适的生成器和正确的标志。只生成所需内容,不多生成。
理念
核心原则:
- 只生成最少内容 — 需要模型时使用
model,而不是scaffold。需要迁移时使用migration,而不是model。 - 跳过不需要的内容 — 除非明确需要(或在
config.generators中配置默认值),否则传入--no-helper、--no-assets、--no-jbuilder。 - 了解生成器 — Rails 内置了 30 多种生成器。先了解它们,再手动编写代码。
- 先检查项目默认设置 — 运行任何命令前,先查看
config/application.rb中的config.generators。 - 重新生成前先撤销 — 使用
bin/rails destroy干净地撤销生成器操作,然后再使用不同选项重新运行。
何时使用此技能
- 运行任何
bin/rails generate命令 - 判断哪种生成器适合当前任务
- 在
config/application.rb中自定义生成器默认设置 - 为项目特定模式创建自定义生成器
- 覆盖内置生成器模板
- 了解生成器将创建哪些文件
说明
第 1 步:检查项目生成器配置
先检查现有的生成器配置 — 项目可能已经跳过辅助文件、使用 UUID 或设置了其他默认值:
# Check for custom generator config
grep -A 20 "config.generators" config/application.rb
# See all available generators
bin/rails generate --help
# See specific generator options
bin/rails generate model --help
遵循项目约定。如果项目禁用了辅助文件或使用 UUID,你的生成器也应如此。
第 2 步:选择合适的生成器
选择能满足需求的最具体的生成器:
| 需求 | 生成器 | 不要使用 |
|---|---|---|
| 更改数据库列 | migration | model |
| 创建带表的新模型 | model | scaffold |
| 创建新的控制器和视图 | controller | scaffold |
| 完整的 CRUD 资源 | scaffold | — |
| 仅限 API 的资源 | scaffold --api | scaffold |
| 后台任务 | job | 手动编写 |
| 邮件程序 | mailer | 手动编写 |
| 更改数据库表 | migration | 手动编写 |
生成器层级(从最具体到最不具体):
migration → model → resource → scaffold
↗
controller ------/
每一级都会增加更多文件。始终选择能满足需求的最低层级。
第 3 步:使用正确的标志
需要了解的重要标志:
# Skip unwanted files
--no-helper # Skip helper file (almost always want this)
--no-assets # Skip CSS/JS files
--no-jbuilder # Skip JSON builder views
--no-test-framework # Skip test files (if writing tests separately)
--no-fixture # Skip fixture file only
# Control behavior
--skip-migration # Generate model without migration
--skip-routes # Don't add to routes.rb
--force # Overwrite existing files
--pretend # Dry run — show what would happen
# Field types
title:string # Default type, can omit :string
body:text # Long text
price:decimal # Decimal number
published:boolean # Boolean
published_at:datetime # Timestamp
user:references # Foreign key + belongs_to
tags:jsonb # JSON column (PostgreSQL)
第 4 步:先使用 --pretend 运行
对于会创建多个文件的生成器,先进行试运行 — 检查起来比清理更容易:
# See what would be created without creating it
bin/rails generate scaffold Post title body:text --pretend
这样可以避免生成之后还得清理的不需要文件。
第 5 步:重新生成前先撤销
如果出错了,先撤销:
# Undo a generator completely
bin/rails destroy model Post
bin/rails destroy scaffold Post
bin/rails destroy controller Posts
destroy 会准确移除 generate 创建的内容。不要手动删除文件。
第 6 步:配置默认值
在 config/application.rb 中设置项目级默认值:
config.generators do |g|
g.orm :active_record, primary_key_type: :uuid
g.test_framework :test_unit, fixture: true
g.helper false # Never generate helpers
g.assets false # Never generate assets
g.jbuilder false # Never generate jbuilder views
g.system_tests :test_unit # Or nil to skip
g.template_engine :erb # Or :slim, :haml
g.stylesheets false # Skip stylesheets
g.javascripts false # Skip JS files
end
配置完成后,就不必在每条命令中都添加 --no-helper 等选项。
内置生成器速查
最常用的生成器
| 生成器 | 创建内容 | 示例 |
|---|---|---|
model | 模型 + 迁移 + 测试 + 固件 | bin/rails g model Post title body:text |
migration | 仅迁移文件 | bin/rails g migration AddSlugToPosts slug:string:uniq |
controller | 控制器 + 视图 + 测试 + 路由 + 辅助文件 | bin/rails g controller Posts index show |
scaffold | 模型 + 控制器 + 视图 + 迁移 + 测试 + 路由 | bin/rails g scaffold Post title body:text |
resource | 模型 + 控制器(空)+ 迁移 + 路由 | bin/rails g resource Post title body:text |
其他内置生成器
| 生成器 | 创建内容 | 示例 |
|---|---|---|
job | Job 类 + 测试 | bin/rails g job ProcessPayment |
mailer | Mailer + 视图 + 测试 | bin/rails g mailer UserMailer welcome reset_password |
channel | Action Cable channel + JS | bin/rails g channel Chat speak |
task | Rake 任务 | bin/rails g task feeds fetch |
mailbox | Action Mailbox mailbox + 测试 | bin/rails g mailbox Forwards |
generator | 自定义生成器骨架 | bin/rails g generator my_generator |
integration_test | 集成测试文件 | bin/rails g integration_test UserFlows |
system_test | 系统测试文件 | bin/rails g system_test UserFlows |
scaffold_controller | Controller + 视图(无模型/迁移) | bin/rails g scaffold_controller Post title body:text |
helper | Helper 模块 + 测试 | bin/rails g helper Posts |
迁移名称约定
Rails 根据名称推断迁移行为:
# Add columns (AddXxxToYyy)
bin/rails g migration AddSlugToPosts slug:string:uniq
# Remove columns (RemoveXxxFromYyy)
bin/rails g migration RemoveBodyFromPosts body:text
# Create join table (CreateJoinTableXxxYyy)
bin/rails g migration CreateJoinTablePostsCategories posts categories
# Standalone (no inference — empty change method)
bin/rails g migration UpdatePostsSchema
字段类型参考
# Common types
string # VARCHAR (255 default)
text # TEXT (unlimited)
integer # INT
float # FLOAT
decimal # DECIMAL (use for money)
boolean # BOOLEAN
date # DATE
datetime # DATETIME
timestamp # TIMESTAMP
time # TIME
binary # BLOB
# Special types
references # Foreign key (adds _id column + index + belongs_to)
belongs_to # Alias for references
jsonb # JSONB (PostgreSQL)
json # JSON
uuid # UUID
inet # INET (PostgreSQL)
citext # Case-insensitive text (PostgreSQL)
# Modifiers
title:string{100} # String with limit
price:decimal{8,2} # Precision and scale
slug:string:uniq # Add unique index
slug:string:index # Add index
user:references{polymorphic} # Polymorphic association
创建自定义生成器
何时创建
当项目中存在重复模式时,创建自定义生成器:
- 结构一致的服务对象
- 表单对象
- 查询对象
- 策略类
- 装饰器/呈现器
如何创建
bin/rails generate generator service
创建内容:
lib/generators/service/
├── service_generator.rb
├── USAGE
└── templates/
生成器结构
# lib/generators/service/service_generator.rb
class ServiceGenerator < Rails::Generators::NamedBase
source_root File.expand_path("templates", __dir__)
# Optional: add arguments and options
class_option :async, type: :boolean, default: false,
desc: "Generate an async service with ActiveJob"
def create_service_file
template "service.rb.tt", "app/services/#{file_name}_service.rb"
end
def create_test_file
template "service_test.rb.tt", "test/services/#{file_name}_service_test.rb"
end
private
def async?
options[:async]
end
end
模板文件
# lib/generators/service/templates/service.rb.tt
class <%= class_name %>Service
def initialize(<%= file_name %>)
@<%= file_name %> = <%= file_name %>
end
def call
# TODO: implement
end
private
attr_reader :<%= file_name %>
end
可用模板变量
| 变量 | 示例输入 | 结果 |
|---|---|---|
name | admin/user_cleanup | admin/user_cleanup |
file_name | admin/user_cleanup | user_cleanup |
class_name | admin/user_cleanup | Admin::UserCleanup |
human_name | admin/user_cleanup | Admin user cleanup |
plural_name | user | users |
singular_name | users | user |
table_name | user | users |
file_path | admin/user_cleanup | admin/user_cleanup |
class_path | admin/user_cleanup | ["admin"] |
覆盖内置模板
将文件放入 lib/templates/,即可覆盖任何内置生成器的模板:
lib/templates/
├── erb/
│ └── scaffold/
│ ├── index.html.erb.tt
│ ├── show.html.erb.tt
│ ├── _form.html.erb.tt
│ └── _resource.html.erb.tt
├── rails/
│ └── scaffold_controller/
│ └── controller.rb.tt
└── active_record/
└── migration/
└── create_table_migration.rb.tt
Rails 会先检查 lib/templates/,再检查自身模板。无需配置。
**模板转义:**用于生成 ERB 的生成器模板需要双重转义:
- 模板中的
<%%=→ 输出中的<%= - 模板中的
<%=→ 在生成时求值
Agent 常见错误
-
需要
model时使用scaffold— Scaffold 会创建 controller、视图、路由、helpers 和测试。如果只需要模型,请使用model——减少清理工作,也减少杂项。 -
忘记
--no-helper— 在现代 Rails 中,Helper 文件很少使用。生成它们只会增加杂乱文件。 -
跳过
--pretend— 复杂生成器的试运行只需一秒,就能避免生成之后还得手动清理的文件。 -
手动编写迁移 — 使用命名约定(AddXxxToYyy、RemoveXxxFromYyy)的
bin/rails g migration会自动生成迁移内容,省去手动输入。 -
生成后手动删除文件 — 改用
bin/rails destroy。它会干净地撤销路由添加并删除所有生成的文件。 -
不了解
scaffold_controller— 已有模型但需要 controller 和视图时,请使用scaffold_controller。运行scaffold会尝试重新创建模型。 -
忽略项目默认配置 — 先检查
config.generators。项目可能已经跳过 helpers,此时--no-helper就是多余的。 -
为一次性需求创建自定义生成器 — 重复某种模式 3 次以上时,自定义生成器才值得创建。对于一次性需求,直接编写文件即可。
性能提示
--pretend不耗成本 — 生成前始终用它进行验证- 批量定义字段 —
bin/rails g model Post title body:text published:boolean会创建一个迁移,而不是三个 - 架构变更使用
migration— 不要为了添加列而生成新模型
运行生成器
# Standard
bin/rails generate model Post title body:text
bin/rails g model Post title body:text # Short alias
# Dry run
bin/rails g model Post title --pretend
# Destroy (undo)
bin/rails destroy model Post
bin/rails d model Post # Short alias
# List all available
bin/rails generate --help
# Generator-specific help
bin/rails g model --help
bin/rails g migration --help
bin/rails g scaffold --help
调试生成器
# See what a generator would do
bin/rails g model Post --pretend
# Check generator resolution path
bin/rails g model --help | head -5
# Find where templates live
find lib/templates -name "*.tt" 2>/dev/null
find $(bundle show railties)/lib/rails/generators -name "*.tt" | head -20
# Check current generator config
grep -A 20 "config.generators" config/application.rb
详细参考
完整示例和边缘情况请参阅 references/ 目录:
references/built-in-generators.md— 所有内置生成器及其标志、创建的文件和默认值自定义方法references/custom-generators.md— 创建自定义生成器、钩子/组合和解析顺序references/templates.md— 覆盖内置模板、用于rails new的应用模板references/thor-actions.md— Thor 文件操作方法(create_file、inject_into_file、gsub_file 等)references/testing.md— 生成器测试、边缘情况(STI、UUID、命名空间)、配方和故障排除