CLI Overview
Quick Start Guide
wheels info
wheels reload
wheels deps
wheels destroy
wheels watch
wheels generate app
wheels generate app-wizard
wheels generate controller
wheels generate model
wheels generate view
wheels generate property
wheels generate route
wheels generate resource
wheels generate api-resource
wheels generate frontend
wheels generate test
wheels generate snippets
wheels scaffold
wheels db create
wheels db drop
wheels db setup
wheels db reset
wheels db status
wheels db version
wheels db rollback
wheels db seed
wheels db dump
wheels db restore
wheels db shell
wheels db schema
wheels dbmigrate info
wheels dbmigrate latest
wheels dbmigrate up
wheels dbmigrate down
wheels dbmigrate reset
wheels dbmigrate exec
wheels dbmigrate create blank
wheels dbmigrate create table
wheels dbmigrate create column
wheels dbmigrate remove table
wheels test
wheels test run
wheels test coverage
wheels test debug
wheels config list
wheels config set
wheels config env
wheels env
wheels env setup
wheels env list
wheels env switch
wheels environment
wheels console
wheels runner
wheels server
wheels server start
wheels server stop
wheels server restart
wheels server status
wheels server log
wheels server open
wheels plugins
wheels plugins list
wheels plugins install
wheels plugins remove
wheels analyze
wheels analyze code
wheels analyze performance
wheels analyze security
wheels security
wheels security scan
wheels optimize
wheels optimize performance
wheels docs
wheels docs generate
wheels docs serve
wheels ci init
wheels docker init
wheels docker deploy
wheels deploy
wheels deploy audit
wheels deploy exec
wheels deploy hooks
wheels deploy init
wheels deploy lock
wheels deploy logs
wheels deploy proxy
wheels deploy push
wheels deploy rollback
wheels deploy secrets
wheels deploy setup
wheels deploy status
wheels deploy stop
Configuration Management
Creating Commands
Service Architecture
Migrations Guide
Testing Guide
Object Relational Mapping
Creating Records
Reading Records
Updating Records
Deleting Records
Column Statistics
Dynamic Finders
Getting Paginated Data
Associations
Nested Properties
Object Validation
Object Callbacks
Calculated Properties
Transactions
Dirty Records
Soft Delete
Automatic Time Stamps
Using Multiple Data Sources
wheels generate controller
This command works correctly without options (parameters). Option support is under development and will be available soon.
Generate a controller with actions and optional views.
Synopsis
wheels generate controller [name] [actions] [options]
wheels g controller [name] [actions] [options]
Description
The wheels generate controller
command creates a new controller CFC file with specified actions and optionally generates corresponding view files. It supports both traditional and RESTful controller patterns.
Arguments
| Argument | Description | Default |
|----------|-------------|---------|
| name
| Name of the controller to create (usually plural) | Required |
Options
| Option | Description | Default |
|--------|-------------|---------|
| actions
| Actions to generate (comma-delimited, default: CRUD for REST) | |
| --rest
| Generate RESTful controller with CRUD actions | false
|
| --api
| Generate API controller (no view-related actions) | false
|
| description
| Controller description | |
| --force
| Overwrite existing files | false
|
Examples
Basic controller
wheels generate controller products
Creates:
/controllers/Products.cfc
withindex
action/views/products/index.cfm
Controller with multiple actions
wheels generate controller products actions="index,show,new,create,edit,update,delete"
Creates controller with all CRUD actions and corresponding views.
RESTful controller
wheels generate controller products --rest
Automatically generates all RESTful actions:
index
- List all productsshow
- Show single productnew
- New product formcreate
- Create productedit
- Edit product formupdate
- Update productdelete
- Delete product
API controller
wheels generate controller api/products --api
Creates:
/controllers/api/Products.cfc
with JSON responses- No view files
Custom actions
wheels generate controller reports actions="dashboard,monthly,yearly,export"
Generated Code
Basic Controller
component extends="Controller" {
function init() {
// Constructor
}
function index() {
products = model("Product").findAll();
}
}
RESTful Controller
component extends="Controller" {
function init() {
// Constructor
}
function index() {
products = model("Product").findAll();
}
function show() {
product = model("Product").findByKey(params.key);
if (!IsObject(product)) {
flashInsert(error="Product not found");
redirectTo(action="index");
}
}
function new() {
product = model("Product").new();
}
function create() {
product = model("Product").new(params.product);
if (product.save()) {
flashInsert(success="Product created successfully");
redirectTo(action="index");
} else {
renderView(action="new");
}
}
function edit() {
product = model("Product").findByKey(params.key);
if (!IsObject(product)) {
flashInsert(error="Product not found");
redirectTo(action="index");
}
}
function update() {
product = model("Product").findByKey(params.key);
if (IsObject(product) && product.update(params.product)) {
flashInsert(success="Product updated successfully");
redirectTo(action="index");
} else {
renderView(action="edit");
}
}
function delete() {
product = model("Product").findByKey(params.key);
if (IsObject(product) && product.delete()) {
flashInsert(success="Product deleted successfully");
} else {
flashInsert(error="Could not delete product");
}
redirectTo(action="index");
}
}
API Controller
component extends="Controller" {
function init() {
provides("json");
}
function index() {
products = model("Product").findAll();
renderWith(products);
}
function show() {
product = model("Product").findByKey(params.key);
if (IsObject(product)) {
renderWith(product);
} else {
renderWith({error: "Product not found"}, status=404);
}
}
function create() {
product = model("Product").new(params.product);
if (product.save()) {
renderWith(product, status=201);
} else {
renderWith({errors: product.allErrors()}, status=422);
}
}
function update() {
product = model("Product").findByKey(params.key);
if (IsObject(product) && product.update(params.product)) {
renderWith(product);
} else {
renderWith({errors: product.allErrors()}, status=422);
}
}
function delete() {
product = model("Product").findByKey(params.key);
if (IsObject(product) && product.delete()) {
renderWith({message: "Product deleted"});
} else {
renderWith({error: "Could not delete"}, status=400);
}
}
}
View Generation
Views are automatically generated for non-API controllers:
index.cfm
<h1>Products</h1>
<p>#linkTo(text="New Product", action="new")#</p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<cfloop query="products">
<tr>
<td>#products.name#</td>
<td>
#linkTo(text="Show", action="show", key=products.id)#
#linkTo(text="Edit", action="edit", key=products.id)#
#linkTo(text="Delete", action="delete", key=products.id, method="delete", confirm="Are you sure?")#
</td>
</tr>
</cfloop>
</tbody>
</table>
Naming Conventions
- Controller names: PascalCase, typically plural (Products, Users)
- Action names: camelCase (index, show, createProduct)
- File locations:
- Controllers:
/controllers/
- Nested:
/controllers/admin/Products.cfc
- Views:
/views/{controller}/
- Controllers:
Routes Configuration
Add routes in /config/routes.cfm
:
Traditional Routes
<cfset get(name="products", to="products##index")>
<cfset get(name="product", to="products##show")>
<cfset post(name="products", to="products##create")>
RESTful Resources
<cfset resources("products")>
Nested Resources
<cfset namespace("api")>
<cfset resources("products")>
</cfset>
Testing
Generate tests alongside controllers:
wheels generate controller products --rest
wheels generate test controller products
Best Practices
- Use plural names for resource controllers
- Keep controllers focused on single resources
- Use
--rest
for standard CRUD operations - Implement proper error handling
- Add authentication in
init()
method - Use filters for common functionality
Common Patterns
Authentication Filter
function init() {
filters(through="authenticate", except="index,show");
}
private function authenticate() {
if (!session.isLoggedIn) {
redirectTo(controller="sessions", action="new");
}
}
Pagination
function index() {
products = model("Product").findAll(
page=params.page ?: 1,
perPage=25,
order="createdAt DESC"
);
}
Search
function index() {
if (StructKeyExists(params, "q")) {
products = model("Product").findAll(
where="name LIKE :search OR description LIKE :search",
params={search: "%#params.q#%"}
);
} else {
products = model("Product").findAll();
}
}
See Also
- wheels generate model - Generate models
- wheels generate view - Generate views
- wheels scaffold - Generate complete CRUD
- wheels generate test - Generate controller tests
- Synopsis
- Arguments
- Options
- Examples
- Basic controller
- Controller with multiple actions
- RESTful controller
- API controller
- Custom actions
- Generated Code
- Basic Controller
- RESTful Controller
- API Controller
- View Generation
- index.cfm
- Naming Conventions
- Routes Configuration
- Traditional Routes
- RESTful Resources
- Nested Resources
- Testing
- Best Practices
- Common Patterns
- Authentication Filter
- Pagination
- Search
- See Also