Skip to content

Command Line Tools

wheels generate scaffold

Generate complete CRUD scaffolding for a resource including model, controller, views, tests, and migration.

Terminal window
wheels generate scaffold name [options]
wheels g scaffold name [options]
wheels g resource name [options] # Alias for scaffold

The wheels scaffold command (alias: wheels g resource) generates a complete CRUD (Create, Read, Update, Delete) implementation including model, controller, views, tests, and database migration. It’s the fastest way to create a fully functional resource.

This command supports multiple parameter formats:

  • Positional parameters: wheels generate scaffold Product (resource name)
  • Named parameters: name=value (e.g., name=Product, properties="name:string")
  • Flag parameters: --flag equals flag=true (e.g., --api equals api=true)
  • Flag with value: --flag=value (e.g., --properties="name:string")

Parameter Mixing Rules:

ALLOWED:

  • All positional: wheels generate scaffold Product
  • All named: name=Product properties="name:string"
  • Positional + flags: wheels generate scaffold Product --api --migrate

NOT ALLOWED:

  • Positional + named: wheels generate scaffold Product properties="name:string" (causes error)

Recommendation: Use positional for resource name, flags for options: wheels generate scaffold Product --properties="name:string" --api --migrate

ArgumentDescriptionDefault
nameResource name (singular)Required
OptionDescriptionExampleDefault
--propertiesModel properties (format: name:type,name2:type2)--properties="name:string,price:decimal"
--belongsToParent model relationships (comma-separated)--belongsTo=User,Category
--hasManyChild model relationships (comma-separated)--hasMany=orders,comments
--apiGenerate API-only scaffold (no views)--api=true or --apifalse
--testsGenerate test files--tests=falsetrue
--migrateRun migrations after scaffolding--migrate=true or --migratefalse
--forceOverwrite existing files--force=true or --forcefalse
Terminal window
# Basic scaffold
wheels g scaffold Product
wheels g resource Product # Same as scaffold
# With properties
wheels g scaffold Product --properties="name:string,price:decimal,stock:integer"
wheels g resource Product --properties="name:string,price:decimal,stock:integer"
# With associations
wheels g scaffold Order --properties="total:decimal,status:string" --belongsTo=User --hasMany=orderItems
# API-only scaffold (no views)
wheels g scaffold Product --api --properties="name:string,price:decimal"
wheels g resource Product --api --properties="name:string,price:decimal"
# With auto-migration
wheels g scaffold Category --properties="name:string" --migrate
Terminal window
# Complete e-commerce product
wheels generate scaffold Product --properties="name:string,description:text,price:decimal,inStock:boolean" --belongsTo=Category --hasMany=orderItems,reviews --migrate
# Blog system
wheels generate scaffold Post --properties="title:string,content:text,published:boolean" --belongsTo=User --hasMany=comments --api

Properties Format:

  • Format: --properties="name:type,name2:type2"
  • Types: string, text, integer, decimal, boolean, date, datetime, time
  • Always use quotes around the entire properties string

Associations:

  • --belongsTo=Model1,Model2 (PascalCase parent models)
  • --hasMany=model1,model2 (camelCase plural child models)

Resource Name:

  • Must be singular (e.g., Product, not Products)
  • PascalCase recommended (e.g., OrderItem, UserProfile)
  1. Model (/models/Product.cfc) - Properties, validations, associations
  2. Controller (/controllers/Products.cfc) - All CRUD actions (index, show, new, create, edit, update, delete)
  3. Views (/views/products/) - index, show, new, edit, _form partial
  4. Migration (/app/migrator/migrations/[timestamp]_create_products.cfc) - Table creation with indexes
  5. Tests - Model, controller, and integration tests (if --tests=true)
  1. Model - Same as standard
  2. API Controller - JSON responses only, no views
  3. Migration - Same as standard
  4. API Tests - JSON response tests

For wheels scaffold Product --properties="name:string,price:decimal":

Model: Properties with validations (presence, uniqueness, numerical) Controller: Full CRUD actions with flash messages and error handling Views: List, show, new/edit forms with proper encoding and form helpers Migration: Table with columns, timestamps, and indexes

Run the command to see the complete generated code.

Add to /config/routes.cfm:

<cfset resources("products")>

This creates all RESTful routes (index, new, create, show, edit, update, delete).

  1. Run migration (if not using --migrate): wheels dbmigrate latest
  2. Add routes to /config/routes.cfm: <cfset resources("products")>
  3. Reload application: wheels reload
  4. Test: Visit /products and test CRUD operations

Search:

function index() {
products = StructKeyExists(params, "search")
? model("Product").findAll(where="name LIKE :search", params={search: "%#params.search#%"})
: model("Product").findAll();
}

Pagination:

products = model("Product").findAll(page=params.page ?: 1, perPage=20);

Authentication:

function init() {
filters(through="authenticate", except="index,show");
}

Customize generated code by overriding templates:

  1. Copy templates from /cli/templates/ to /app/snippets/
  2. Modify templates to match your project style
  3. CLI uses your custom templates automatically

Available Templates:

  • crud/index.txt, crud/show.txt, crud/new.txt, crud/edit.txt, crud/_form.txt
  • ModelContent.txt, ControllerContent.txt

Template Placeholders:

  • |ObjectNameSingular|, |ObjectNamePlural| - Lowercase names
  • |ObjectNameSingularC|, |ObjectNamePluralC| - Capitalized names
  • |FormFields| - Generated form fields

Wrong:

Terminal window
wheels generate scaffold Product properties="name:string" # Positional + named (ERROR)
wheels generate scaffold Product --properties=name:string # Missing quotes
wheels generate scaffold Comment --belongsTo=product # Wrong case (should be Product)

Correct:

Terminal window
wheels generate scaffold Product --properties="name:string,price:decimal"
wheels generate scaffold Comment --belongsTo=Product --hasMany=replies

Rules:

  • Always use quotes around properties: --properties="name:string"
  • Use PascalCase for belongsTo: --belongsTo=User
  • Use camelCase plural for hasMany: --hasMany=posts,comments
  • Never mix positional and named parameters

Problem: Files not created or partially generated

Solutions:

  • Check directory permissions: ls -la app/models app/controllers
  • Use --force to overwrite existing files
  • Use singular PascalCase names (e.g., Product, not products or product-item)

Problem: Migrations not created or contain errors

Solutions:

  • Use valid property types: string, text, integer, decimal, boolean, date, datetime
  • Check generated migration: ls app/migrator/migrations/*create*
  • Foreign keys are auto-generated for associations

Problem: Routes not working

Solution: Add resources to /config/routes.cfm:

<cfscript>
mapper()
.resources("products")
.wildcard()
.end();
</cfscript>

Before scaffolding:

  1. Verify Wheels directory structure exists
  2. Check for naming conflicts
  3. Plan properties and associations

After scaffolding:

  1. Check files were created: ls app/models/ app/controllers/ app/views/
  2. Run migrations: wheels dbmigrate latest
  3. Add routes to routes.cfm
  4. Test at /products
  1. Plan First: Define properties, associations, and validations before scaffolding
  2. Start Simple: Begin with basic properties, add complexity later
  3. Use Templates: Customize templates in /app/snippets/ to match your project standards
  4. Test Immediately: Run generated tests and visit the scaffold in browser
  5. Security: Add authentication/authorization filters after generation
  6. Incremental: Scaffold one resource at a time, test, then move to the next