Command Line Tools
wheels generate model
wheels generate model
Section titled “wheels generate model”Generate a model with properties, validations, and associations.
Synopsis
Section titled “Synopsis”wheels generate model name=<modelName> [options]
#Can also be used as:wheels g model name=<modelName> [options]CommandBox Parameter Syntax
Section titled “CommandBox Parameter Syntax”- Named parameters:
param=value(e.g.,name=User,properties=name:string,email:string) - Flag parameters:
--flagequalsflag=true(e.g.,--migrationequalsmigration=true) - Param with value:
--param=valueequalsparam=value(e.g.,--primaryKey=uuid)
Recommended: Use flags for options: wheels generate model name=User --properties="name:string,email:string" --migration
Description
Section titled “Description”The wheels generate model command creates a new model CFC file with optional properties, associations, and database migrations. Models represent database tables and contain business logic, validations, and relationships.
Arguments
Section titled “Arguments”| Argument | Description | Default |
|---|---|---|
name | Model name (singular) | Required |
Model Name Validation
Section titled “Model Name Validation”- Must be singular (User, not Users)
- Must be PascalCase (User, BlogPost)
- Cannot contain spaces or special characters
- Must be valid CFML component name
Options
Section titled “Options”| Option | Description | Valid Values | Default |
|---|---|---|---|
properties | Model properties (format: name:type,name2:type2) | Property format: name:type[,name2:type2] where type is valid column type | "" |
belongsTo | Parent model relationships (comma-separated) | Valid model names (PascalCase), comma-separated | "" |
hasMany | Child model relationships (comma-separated) | Valid model names (PascalCase), comma-separated | "" |
hasOne | One-to-one relationships (comma-separated) | Valid model names (PascalCase), comma-separated | "" |
primaryKey | Primary key column name(s) | Valid column name (alphanumeric, underscore) | id |
tableName | Custom database table name | Valid table name (alphanumeric, underscore) | "" |
description | Model description | Any descriptive text | "" |
migration | Generate database migration | true, false | true |
force | Overwrite existing files | true, false | false |
Relationship Validation
Section titled “Relationship Validation”- Relationship model names must follow model naming conventions
- Models referenced in relationships should exist or be created
- Comma-separated values cannot contain spaces around commas
Property Types
Section titled “Property Types”| Type | Database Type | CFML Type |
|---|---|---|
string | VARCHAR(255) | string |
text | TEXT | string |
integer | INTEGER | numeric |
biginteger | BIGINT | numeric |
float | FLOAT | numeric |
decimal | DECIMAL(10,2) | numeric |
boolean | BOOLEAN | boolean |
date | DATE | date |
datetime | DATETIME | date |
timestamp | TIMESTAMP | date |
binary | BLOB | binary |
uuid | VARCHAR(35) | string |
Examples
Section titled “Examples”Basic model
Section titled “Basic model”wheels generate model name=UserCreates:
/models/User.cfc- Migration file (if enabled)
Model with properties
Section titled “Model with properties”wheels generate model name=User --properties="firstName:string,lastName:string,email:string,age:integer"Model with associations
Section titled “Model with associations”wheels generate model name=Post --belongsTo="User" --hasMany="Comments"Model without migration
Section titled “Model without migration”wheels generate model name=Setting --migration=falseComplex model
Section titled “Complex model”wheels generate model name=Product --properties="name:string,price:decimal,stock:integer,active:boolean" --belongsTo="Category,Brand" --hasMany="Reviews,OrderItems"Invalid Model Names
Section titled “Invalid Model Names”# Error: Model name cannot be emptywheels generate model name=""# Result: Invalid model name error
# Error: Model name should be singularwheels generate model name=Users# Result: Warning about plural name
# Error: Invalid characterswheels generate model name="Blog Post"# Result: Invalid model name errorInvalid Property Types
Section titled “Invalid Property Types”# Error: Invalid property typewheels generate model name=User --properties="name:varchar,age:int"# Result: Use 'string' instead of 'varchar', 'integer' instead of 'int'
# Error: Missing property typewheels generate model name=User --properties="name,email:string"# Result: Property format must be 'name:type'Important Validation Rules:
- Model names must be singular and PascalCase (User, not Users or user)
- Property format:
name:type,name2:type2(no spaces) - Relationship names must be PascalCase (User, not user)
- Use valid property types from the table above
Basic Model Examples
Section titled “Basic Model Examples”Basic Model
Section titled “Basic Model”component extends="Model" {
function init() { // Table name (optional if following conventions) table("users");
// Validations validatesPresenceOf("email"); validatesUniquenessOf("email"); validatesFormatOf("email", regex="^[^@]+@[^@]+\.[^@]+$");
// Callbacks beforeCreate("setDefaultValues"); }
private function setDefaultValues() { if (!StructKeyExists(this, "createdAt")) { this.createdAt = Now(); } }
}Model with Properties and Validations
Section titled “Model with Properties and Validations”component extends="Model" {
function init() { // Properties property(name="firstName", label="First Name"); property(name="lastName", label="Last Name"); property(name="email", label="Email Address"); property(name="age", label="Age");
// Validations validatesPresenceOf("firstName,lastName,email"); validatesUniquenessOf("email"); validatesFormatOf("email", regex="^[^@]+@[^@]+\.[^@]+$"); validatesNumericalityOf("age", onlyInteger=true, greaterThan=0, lessThan=150); }
}Model with Associations
Section titled “Model with Associations”component extends="Model" {
function init() { // Associations belongsTo("user"); hasMany("comments", dependent="deleteAll");
// Nested properties nestedProperties(associations="comments", allowDelete=true);
// Validations validatesPresenceOf("title,content,userId"); validatesLengthOf("title", maximum=255); }
}Common Validation Methods
Section titled “Common Validation Methods”// PresencevalidatesPresenceOf("name,email");
// UniquenessvalidatesUniquenessOf("email,username");
// FormatvalidatesFormatOf("email", regex="^[^@]+@[^@]+\.[^@]+$");validatesFormatOf("phone", regex="^\d{3}-\d{3}-\d{4}$");
// LengthvalidatesLengthOf("username", minimum=3, maximum=20);validatesLengthOf("bio", maximum=500);
// NumericalvalidatesNumericalityOf("age", onlyInteger=true, greaterThan=0);validatesNumericalityOf("price", greaterThan=0);
// Inclusion/ExclusionvalidatesInclusionOf("status", list="active,inactive,pending");validatesExclusionOf("username", list="admin,root,system");
// ConfirmationvalidatesConfirmationOf("password");
// Customvalidate("customValidation");Common Association Methods
Section titled “Common Association Methods”Belongs To
Section titled “Belongs To”belongsTo("user");belongsTo(name="author", modelName="user", foreignKey="authorId");Has Many
Section titled “Has Many”hasMany("comments");hasMany(name="posts", dependent="deleteAll", orderBy="createdAt DESC");Has One
Section titled “Has One”hasOne("profile");hasOne(name="address", dependent="delete");Many to Many
Section titled “Many to Many”hasMany("categorizations");hasMany(name="categories", through="categorizations");Common Callbacks
Section titled “Common Callbacks”// Before callbacksbeforeCreate("method1,method2");beforeUpdate("method3");beforeSave("method4");beforeDelete("method5");beforeValidation("method6");
// After callbacksafterCreate("method7");afterUpdate("method8");afterSave("method9");afterDelete("method10");afterValidation("method11");afterFind("method12");afterInitialization("method13");Best Practices
Section titled “Best Practices”- Naming: Use singular names (User, not Users)
- Properties: Define all database columns with correct types
- Validations: Add comprehensive validations in model code
- Associations: Define all relationships using PascalCase
- Callbacks: Use for automatic behaviors
- Indexes: Add to migration for performance
- Validation: Always validate parameters before running command
Common Patterns
Section titled “Common Patterns”Soft Deletes
Section titled “Soft Deletes”function init() { softDeletes();}Calculated Properties
Section titled “Calculated Properties”function init() { property(name="fullName", sql="firstName + ' ' + lastName");}Scopes
Section titled “Scopes”function scopeActive() { return where("active = ?", [true]);}
function scopeRecent(required numeric days=7) { return where("createdAt >= ?", [DateAdd("d", -arguments.days, Now())]);}Default Values
Section titled “Default Values”function init() { beforeCreate("setDefaults");}
private function setDefaults() { if (!StructKeyExists(this, "status")) { this.status = "pending"; } if (!StructKeyExists(this, "priority")) { this.priority = 5; }}Testing
Section titled “Testing”Generate model tests:
wheels generate model name=User --properties="email:string,name:string"wheels generate test type=model name=UserSee Also
Section titled “See Also”- wheels dbmigrate create table - Create migrations
- wheels generate property - Add properties to existing models
- wheels generate controller - Generate controllers
- wheels scaffold - Generate complete CRUD