| name | generators |
| description | Expert guidance for using and creating Rails generators. Use when running "rails generate", "rails g", scaffolding resources, generating models, controllers, migrations, mailers, jobs, or any generated code. Also use for creating custom generators, customizing generator defaults, overriding generator templates, or configuring config.generators. Covers all built-in generators, their flags, and when to use (or not use) each one. |
| allowed-tools | Read, Grep, Glob, Write, Edit, Bash(bin/rails generate*), Bash(bin/rails g*), Bash(bin/rails destroy*), Bash(bin/rails d*) |
Rails Generators Expert
Use the right generator with the right flags. Generate exactly what you need — nothing more.
Philosophy
Core Principles:
- Generate the minimum — Use
model when you need a model, not scaffold. Use migration when you need a migration, not model.
- Skip what you won't use — Pass
--no-helper, --no-assets, --no-jbuilder unless explicitly needed (or configure defaults in config.generators).
- Know your generators — Rails has 30+ built-in generators. Learn them before writing code by hand.
- Check project defaults first — Read
config/application.rb for config.generators before running anything.
- Destroy before regenerating — Use
bin/rails destroy to cleanly undo a generator before re-running with different options.
When To Use This Skill
- Running any
bin/rails generate command
- Deciding which generator fits the task
- Customizing generator defaults in
config/application.rb
- Creating custom generators for project-specific patterns
- Overriding built-in generator templates
- Understanding what files a generator will create
Instructions
Step 1: Check Project Generator Config
Check existing generator configuration first — the project may already skip helpers, use UUIDs, or set other defaults:
grep -A 20 "config.generators" config/application.rb
bin/rails generate --help
bin/rails generate model --help
Match project conventions. If the project disables helpers or uses UUIDs, your generators should too.
Step 2: Choose the Right Generator
Pick the most specific generator that does what you need:
| Need | Generator | NOT |
|---|
| Database column change | migration | model |
| New model with table | model | scaffold |
| New controller + views | controller | scaffold |
| Full CRUD resource | scaffold | — |
| API-only resource | scaffold --api | scaffold |
| Background job | job | Writing by hand |
| Mailer | mailer | Writing by hand |
| Database table change | migration | Writing by hand |
The Generator Hierarchy (most → least specific):
migration → model → resource → scaffold
↗
controller ------/
Each level adds more files. Always pick the lowest level that satisfies the requirement.
Step 3: Use the Right Flags
Essential flags to know:
--no-helper
--no-assets
--no-jbuilder
--no-test-framework
--no-fixture
--skip-migration
--skip-routes
--force
--pretend
title:string
body:text
price:decimal
published:boolean
published_at:datetime
user:references
tags:jsonb
Step 4: Run with --pretend First
For any generator that creates multiple files, dry-run first — it's easier to verify than to clean up:
bin/rails generate scaffold Post title body:text --pretend
This prevents generating unwanted files you'll have to clean up.
Step 5: Destroy Before Regenerating
If you made a mistake, destroy first:
bin/rails destroy model Post
bin/rails destroy scaffold Post
bin/rails destroy controller Posts
destroy removes exactly what generate created. Don't manually delete files.
Step 6: Configure Defaults
Set project-wide defaults in 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
g.assets false
g.jbuilder false
g.system_tests :test_unit
g.template_engine :erb
g.stylesheets false
g.javascripts false
end
Once configured, you don't need --no-helper etc. on every command.
Built-In Generators Quick Reference
Most Used
| Generator | Creates | Example |
|---|
model | Model + migration + test + fixture | bin/rails g model Post title body:text |
migration | Migration file only | bin/rails g migration AddSlugToPosts slug:string:uniq |
controller | Controller + views + test + route + helper | bin/rails g controller Posts index show |
scaffold | Model + controller + views + migration + tests + routes | bin/rails g scaffold Post title body:text |
resource | Model + controller (empty) + migration + route | bin/rails g resource Post title body:text |
Other Built-In
| Generator | Creates | Example |
|---|
job | Job class + test | bin/rails g job ProcessPayment |
mailer | Mailer + views + test | bin/rails g mailer UserMailer welcome reset_password |
channel | Action Cable channel + JS | bin/rails g channel Chat speak |
task | Rake task | bin/rails g task feeds fetch |
mailbox | Action Mailbox mailbox + test | bin/rails g mailbox Forwards |
generator | Custom generator skeleton | bin/rails g generator my_generator |
integration_test | Integration test file | bin/rails g integration_test UserFlows |
system_test | System test file | bin/rails g system_test UserFlows |
scaffold_controller | Controller + views (no model/migration) | bin/rails g scaffold_controller Post title body:text |
helper | Helper module + test | bin/rails g helper Posts |
Migration Name Conventions
Rails infers migration behavior from the name:
bin/rails g migration AddSlugToPosts slug:string:uniq
bin/rails g migration RemoveBodyFromPosts body:text
bin/rails g migration CreateJoinTablePostsCategories posts categories
bin/rails g migration UpdatePostsSchema
Field Type Reference
string
text
integer
float
decimal
boolean
date
datetime
timestamp
time
binary
references
belongs_to
jsonb
json
uuid
inet
citext
title:string{100}
price:decimal{8,2}
slug:string:uniq
slug:string:index
user:references{polymorphic}
Creating Custom Generators
When to Create One
Create a custom generator when your project has repeating patterns:
- Service objects with consistent structure
- Form objects
- Query objects
- Policy classes
- Decorators/presenters
How to Create
bin/rails generate generator service
Creates:
lib/generators/service/
├── service_generator.rb
├── USAGE
└── templates/
Generator Anatomy
class ServiceGenerator < Rails::Generators::NamedBase
source_root File.expand_path("templates", __dir__)
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
Template Files
class <%= class_name %>Service
def initialize(<%= file_name %>)
@<%= file_name %> = <%= file_name %>
end
def call
end
private
attr_reader :<%= file_name %>
end
Available Template Variables
| Variable | Example Input | Result |
|---|
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"] |
Overriding Built-In Templates
Override any built-in generator's templates by placing files in 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 checks lib/templates/ before its own templates. No config needed.
Template escaping: Generator templates that produce ERB need double escaping:
<%%= in template → <%= in output
<%= in template → evaluated at generation time
Common Agent Mistakes
-
Using scaffold when model suffices — Scaffold creates controller, views, routes, helpers, and tests. If you only need a model, use model — less cleanup, less noise.
-
Forgetting --no-helper — Helper files are rarely used in modern Rails. Generating them just adds clutter.
-
Skipping --pretend — Dry-running complex generators takes a second and prevents generating files you'll have to manually clean up.
-
Writing migrations by hand — bin/rails g migration with naming conventions (AddXxxToYyy, RemoveXxxFromYyy) auto-generates the body. Save the typing.
-
Generating then manually deleting files — Use bin/rails destroy instead. It cleanly reverts route additions and removes all generated files.
-
Not knowing about scaffold_controller — When you have a model but need controller+views, use scaffold_controller. Running scaffold would try to recreate the model.
-
Ignoring project defaults — Check config.generators first. The project may already skip helpers, making --no-helper redundant.
-
Creating custom generators for one-offs — Custom generators pay off when you repeat a pattern 3+ times. For one-offs, just write the files.
Performance Tips
--pretend is free — Always use it to verify before generating
- Batch field definitions —
bin/rails g model Post title body:text published:boolean is one migration, not three
- Use
migration for schema changes — Don't generate a new model to add a column
Running Generators
bin/rails generate model Post title body:text
bin/rails g model Post title body:text
bin/rails g model Post title --pretend
bin/rails destroy model Post
bin/rails d model Post
bin/rails generate --help
bin/rails g model --help
bin/rails g migration --help
bin/rails g scaffold --help
Debugging Generators
bin/rails g model Post --pretend
bin/rails g model --help | head -5
find lib/templates -name "*.tt" 2>/dev/null
find $(bundle show railties)/lib/rails/generators -name "*.tt" | head -20
grep -A 20 "config.generators" config/application.rb
Detailed Reference
See the references/ directory for complete examples and edge cases:
references/built-in-generators.md — All built-in generators with flags, files created, and customizing defaults
references/custom-generators.md — Creating custom generators, hooks/composition, resolution order
references/templates.md — Overriding built-in templates, application templates for rails new
references/thor-actions.md — Thor file manipulation methods (create_file, inject_into_file, gsub_file, etc.)
references/testing.md — Generator testing, edge cases (STI, UUID, namespaces), recipes, troubleshooting