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 property
This command works correctly without options (parameters). Option support is under development and will be available soon.
Add properties to existing model files.
Synopsis
wheels generate property [name] [options]
wheels g property [name] [options]
Description
The wheels generate property
command generates a database migration to add a property to an existing model and scaffolds it into _form.cfm
and show.cfm
views.
Arguments
| Argument | Description | Default |
|----------|-------------|---------|
| name
| Table name | Required |
Options
| Option | Description | Default |
|--------|-------------|---------|
| column-name
| Name of column | Required |
| data-type
| Type of column | string
|
| default
| Default value for column | |
| --null
| Whether to allow null values | |
| limit
| Character or integer size limit for column | |
| precision
| Precision value for decimal columns | |
| scale
| Scale value for decimal columns | |
Property Syntax
Basic Format
propertyName:type:option1:option2
Data Type Options
biginteger
- Large integerbinary
- Binary databoolean
- Boolean (true/false)date
- Date onlydatetime
- Date and timedecimal
- Decimal numbersfloat
- Floating pointinteger
- Integerstring
- Variable character (VARCHAR)text
- Long texttime
- Time onlytimestamp
- Timestampuuid
- UUID/GUID
Examples
String property
wheels generate property user column-name=firstname
Creates a string/textField property called firstname
on the User model.
Boolean property with default
wheels generate property user column-name=isActive data-type=boolean default=0
Creates a boolean/checkbox property with default value of 0 (false).
Datetime property
wheels generate property user column-name=lastloggedin data-type=datetime
Creates a datetime property on the User model.
Decimal property with precision
wheels generate property product column-name=price data-type=decimal precision=10 scale=2
Add calculated property
wheels generate property user "fullName:calculated"
Generated Code Examples
Basic Property Addition
Before:
component extends="Model" {
function init() {
// Existing code
}
}
After:
component extends="Model" {
function init() {
// Existing code
// Properties
property(name="email", sql="email");
// Validations
validatesPresenceOf(properties="email");
validatesUniquenessOf(properties="email");
validatesFormatOf(property="email", regEx="^[^@\s]+@[^@\s]+\.[^@\s]+$");
}
}
Multiple Properties
Command:
wheels generate property product "name:string:required description:text price:float:required:default=0.00 inStock:boolean:default=true"
Generated:
component extends="Model" {
function init() {
// Properties
property(name="name", sql="name");
property(name="description", sql="description");
property(name="price", sql="price", default=0.00);
property(name="inStock", sql="in_stock", default=true);
// Validations
validatesPresenceOf(properties="name,price");
validatesNumericalityOf(property="price", allowBlank=false, greaterThanOrEqualTo=0);
}
}
Association Property
Command:
wheels generate property comment "userId:integer:required:belongsTo=user postId:integer:required:belongsTo=post"
Generated:
component extends="Model" {
function init() {
// Associations
belongsTo(name="user", foreignKey="userId");
belongsTo(name="post", foreignKey="postId");
// Properties
property(name="userId", sql="user_id");
property(name="postId", sql="post_id");
// Validations
validatesPresenceOf(properties="userId,postId");
}
}
Calculated Property
Command:
wheels generate property user fullName:calculated --callbacks
Generated:
component extends="Model" {
function init() {
// Properties
property(name="fullName", sql="", calculated=true);
}
// Calculated property getter
function getFullName() {
return this.firstName & " " & this.lastName;
}
}
Migration Generation
When --migrate=true
(default), generates migration:
Migration File
app/migrator/migrations/[timestamp]_add_properties_to_[model].cfc
:
component extends="wheels.migrator.Migration" hint="Add properties to product" {
function up() {
transaction {
addColumn(table="products", columnName="sku", columnType="string", limit=50, null=false);
addColumn(table="products", columnName="price", columnType="decimal", precision=10, scale=2, null=false, default=0.00);
addColumn(table="products", columnName="stock", columnType="integer", null=true, default=0);
addIndex(table="products", columnNames="sku", unique=true);
}
}
function down() {
transaction {
removeIndex(table="products", columnNames="sku");
removeColumn(table="products", columnName="stock");
removeColumn(table="products", columnName="price");
removeColumn(table="products", columnName="sku");
}
}
}
Validation Rules
Automatic Validations
Based on property type and options:
| Type | Validations Applied |
|------|-------------------|
| string:required
| validatesPresenceOf, validatesLengthOf |
| string:unique
| validatesUniquenessOf |
| email
| validatesFormatOf with email regex |
| integer
| validatesNumericalityOf(onlyInteger=true) |
| float
| validatesNumericalityOf |
| boolean
| validatesInclusionOf(list="true,false,0,1") |
| date
| validatesFormatOf with date pattern |
Custom Validations
Add custom validation rules:
wheels generate property user "age:integer:min=18:max=120"
Generated:
validatesNumericalityOf(property="age", greaterThanOrEqualTo=18, lessThanOrEqualTo=120);
Property Callbacks
Generate with callbacks:
wheels generate property user lastLoginAt:datetime --callbacks
Generated:
function init() {
// Properties
property(name="lastLoginAt", sql="last_login_at");
// Callbacks
beforeUpdate("updateLastLoginAt");
}
private function updateLastLoginAt() {
if (hasChanged("lastLoginAt")) {
// Custom logic here
}
}
Complex Properties
Enum-like Property
wheels generate property order "status:string:default=pending:inclusion=pending,processing,shipped,delivered"
Generated:
property(name="status", sql="status", default="pending");
validatesInclusionOf(property="status", list="pending,processing,shipped,delivered");
File Upload Property
wheels generate property user "avatar:string:fileField"
Generated:
property(name="avatar", sql="avatar");
// In the init() method
afterSave("processAvatarUpload");
beforeDelete("deleteAvatarFile");
private function processAvatarUpload() {
if (hasChanged("avatar") && isUploadedFile("avatar")) {
// Handle file upload
}
}
JSON Property
wheels generate property user "preferences:text:json"
Generated:
property(name="preferences", sql="preferences");
function getPreferences() {
if (isJSON(this.preferences)) {
return deserializeJSON(this.preferences);
}
return {};
}
function setPreferences(required struct value) {
this.preferences = serializeJSON(arguments.value);
}
Property Modifiers
Encrypted Property
wheels generate property user "ssn:string:encrypted"
Generated:
property(name="ssn", sql="ssn");
beforeSave("encryptSSN");
afterFind("decryptSSN");
private function encryptSSN() {
if (hasChanged("ssn") && Len(this.ssn)) {
this.ssn = encrypt(this.ssn, application.encryptionKey);
}
}
private function decryptSSN() {
if (Len(this.ssn)) {
this.ssn = decrypt(this.ssn, application.encryptionKey);
}
}
Slugged Property
wheels generate property post "slug:string:unique:fromProperty=title"
Generated:
property(name="slug", sql="slug");
validatesUniquenessOf(property="slug");
beforeValidation("generateSlug");
private function generateSlug() {
if (!Len(this.slug) && Len(this.title)) {
this.slug = createSlug(this.title);
}
}
private function createSlug(required string text) {
return reReplace(
lCase(trim(arguments.text)),
"[^a-z0-9]+",
"-",
"all"
);
}
Batch Operations
Add Multiple Related Properties
wheels generate property user "
profile.bio:text
profile.website:string
profile.twitter:string
profile.github:string
" --nested
Add Timestamped Properties
wheels generate property post "publishedAt:timestamp deletedAt:timestamp:nullable"
Integration with Existing Code
Preserve Existing Structure
The command intelligently adds properties without disrupting:
- Existing properties
- Current validations
- Defined associations
- Custom methods
- Comments and formatting
Conflict Resolution
wheels generate property user email:string
> Property 'email' already exists. Options:
> 1. Skip this property
> 2. Update existing property
> 3. Add with different name
> Choice:
Best Practices
- Add properties incrementally
- Always generate migrations
- Include appropriate validations
- Use semantic property names
- Add indexes for query performance
- Consider default values carefully
- Document complex properties
Common Patterns
Soft Delete
wheels generate property model deletedAt:timestamp:nullable
Versioning
wheels generate property document "version:integer:default=1 versionedAt:timestamp"
Status Tracking
wheels generate property order "status:string:default=pending statusChangedAt:timestamp"
Audit Fields
wheels generate property model "createdBy:integer:belongsTo=user updatedBy:integer:belongsTo=user"
Testing
After adding properties:
# Run migration
wheels dbmigrate latest
# Generate property tests
wheels generate test model user
# Run tests
wheels test
See Also
- wheels generate model - Generate models
- wheels dbmigrate create column - Create columns
- wheels generate test - Generate tests
- Synopsis
- Arguments
- Options
- Property Syntax
- Basic Format
- Data Type Options
- Examples
- String property
- Boolean property with default
- Datetime property
- Decimal property with precision
- Add calculated property
- Generated Code Examples
- Basic Property Addition
- Multiple Properties
- Association Property
- Calculated Property
- Migration Generation
- Migration File
- Validation Rules
- Automatic Validations
- Custom Validations
- Property Callbacks
- Complex Properties
- Enum-like Property
- File Upload Property
- JSON Property
- Property Modifiers
- Encrypted Property
- Slugged Property
- Batch Operations
- Add Multiple Related Properties
- Add Timestamped Properties
- Integration with Existing Code
- Preserve Existing Structure
- Conflict Resolution
- Best Practices
- Common Patterns
- Soft Delete
- Versioning
- Status Tracking
- Audit Fields
- Testing
- See Also