API | Wheels

accessibleProperties()

Model Configuration Miscellaneous Functions void model

Use this method to specify which properties can be set through mass assignment.

Name Type Required Default Description
properties string No Property name (or list of property names) that are allowed to be altered through mass assignment.
// 1. Allow only `isActive` to be set through mass assignment (e.g. `updateAll()`, `new()`, `update()`).
config() {
	accessibleProperties("isActive");
}

// 2. Allow a comma-delimited list of properties to be set through mass assignment.
//    Any property not in this list is silently ignored when set via mass assignment.
config() {
	accessibleProperties("firstName,lastName,email");
}

addColumn()

Migrator Migration Functions void migration

adds a column to existing table Only available in a migration CFC

Name Type Required Default Description
table string Yes The Name of the table to add the column to
columnType string Yes The type of the new column
columnName string No The name of the new column
columnNames string No Modern alias for columnName (matches the plural form every TableDefinition column helper accepts). Pass one or the other — not both.
afterColumn string No The name of the column which this column should be inserted after
referenceName string No Name for new reference column, see documentation for references function, required if columnType is 'reference'
default any No Default value for this column
allowNull boolean No Whether to allow NULL values
limit numeric No Character or integer size limit for column
precision numeric No precision value for decimal columns, i.e. number of digits the column can hold
scale numeric No scale value for decimal columns, i.e. number of digits that can be placed to the right of the decimal point (must be less than or equal to precision)
// 1. Add a simple string column to an existing table
addColumn(table="members", columnType="string", columnName="status", limit=50);

// 2. Add a boolean column with a default value and no NULLs allowed
addColumn(
    table="members",
    columnType="boolean",
    columnName="isActive",
    default=1,
    allowNull=false
);

// 3. Add a decimal column with precision and scale (e.g. for a price field)
addColumn(
    table="products",
    columnType="decimal",
    columnName="price",
    precision=10,
    scale=2,
    default=0,
    allowNull=false
);

addError()

Model Object Error Functions void model

Adds an error on a specific property.

Name Type Required Default Description
property string Yes The name of the property you want to add an error on.
message string Yes The error message (such as "Please enter a correct name in the form field" for example).
name string No A name to identify the error by (useful when you need to distinguish one error from another one set on the same object and you don't want to use the error message itself for that).
// 1. Add an error to the `email` property.
this.addError(property="email", message="Sorry, you are not allowed to use that email. Try again, please.");

// 2. Add a named error so you can distinguish it from other errors on the same property.
this.addError(property="email", message="That email address is already taken.", name="emailTaken");

// 3. Check for the named error after adding it.
this.addError(property="username", message="Username is reserved.", name="reservedUsername");
if (this.hasErrors(property="username", name="reservedUsername")) {
	writeOutput("A reserved-username error is present.");
}

addErrorToBase()

Model Object Error Functions void model

Adds an error on the object as a whole (not tied to any specific property).

Name Type Required Default Description
message string Yes The error message (such as "Please enter a correct name in the form field" for example).
name string No A name to identify the error by (useful when you need to distinguish one error from another one set on the same object and you don't want to use the error message itself for that).
// 1. Add a general error on the object (not tied to any single property)
user = model("User").findByKey(params.userId);
user.addErrorToBase(message="Your account has been locked. Please contact support.");

// 2. Add a named base error so it can be targeted or cleared later
order = model("Order").findByKey(params.orderId);
order.addErrorToBase(message="This order cannot be placed outside business hours.", name="businessHoursViolation");
if (order.hasErrors(name="businessHoursViolation")) {
    // handle the named error
}

// 3. Use addErrorToBase inside a custom validation method on the model
function validate() {
    if (this.totalAmount > creditLimit()) {
        this.addErrorToBase(message="The total amount exceeds your available credit limit.");
    }
}

addForeignKey()

Migrator Migration Functions void migration

Add a foreign key constraint to the database, using the reference name that was used to create it Only available in a migration CFC

Name Type Required Default Description
table string Yes The table name to perform the operation on
referenceTable string Yes The reference table name to perform the operation on
column string No The column name to perform the operation on
columnName string No Modern alias for column (consistent with the rest of the migrator surface).
referenceColumn string Yes The reference column name to perform the operation on
// 1. Add a foreign key from orders.customerId to customers.id
addForeignKey(
    table="orders",
    referenceTable="customers",
    column="customerId",
    referenceColumn="id"
);

// 2. Add a foreign key from comments.postId to posts.id
addForeignKey(
    table="comments",
    referenceTable="posts",
    column="postId",
    referenceColumn="id"
);

// 3. Use addForeignKey in a migration's up() and remove it in down()
// In your migration CFC:
//
// public void function up() {
//     addForeignKey(
//         table="order_items",
//         referenceTable="orders",
//         column="orderId",
//         referenceColumn="id"
//     );
// }
//
// public void function down() {
//     dropForeignKey(table="order_items", keyName="FK_order_items_orders");
// }

addFormat()

Configuration Miscellaneous Functions void controller model mapper migrator migration tabledefinition

Adds a new MIME type to your Wheels application for use with responding to multiple formats.

Name Type Required Default Description
extension string Yes File extension to add.
mimeType string Yes Matching MIME type to associate with the file extension.
// 1. Add the `js` format
addFormat(extension="js", mimeType="text/javascript");

// 2. Add the `ppt` and `pptx` formats
addFormat(extension="ppt", mimeType="application/vnd.ms-powerpoint");
addFormat(extension="pptx", mimeType="application/vnd.ms-powerpoint");

// 3. Add a custom `csv` format so controllers can respond with `responds(formats="csv")`
addFormat(extension="csv", mimeType="text/csv");

addIndex()

Migrator Migration Functions void migration

Add database index on a table column Only available in a migration CFC

Name Type Required Default Description
table string Yes The table name to perform the index operation on
columnNames string No One or more column names to index, comma separated
unique boolean No false If true will create a unique index constraint
indexName string No The name of the index to add: Defaults to table name + underscore + first column name
// 1. Add a basic index on a single column
addIndex(table="users", columnNames="email");

// 2. Add a unique index to enforce uniqueness on a column
addIndex(table="members", columnNames="username", unique=true);

// 3. Add a composite index on multiple columns
addIndex(table="orders", columnNames="customerId,createdAt");

// 4. Add an index with a custom index name
// (defaults to tableName_firstColumnName, e.g. "posts_publishedAt")
addIndex(table="posts", columnNames="publishedAt", indexName="idx_posts_published");

addRecord()

Migrator Migration Functions void migration

Adds a record to a table Only available in a migration CFC

Name Type Required Default Description
table string Yes The table name to add the record to
// 1. Insert a simple seed record into a settings table
addRecord(
    table = "settings",
    name = "siteName",
    value = "My Wheels App"
);

// 2. Insert a record with multiple columns (extra keyword arguments become column/value pairs)
addRecord(
    table = "people",
    id = 1,
    title = "Mr",
    firstName = "Bruce",
    lastName = "Wayne",
    email = "bruce@wayneenterprises.com",
    phone = "555-678-9099"
);

// 3. Seed an admin user role during a migration's up() function
component extends="wheels.migrator.Migration" {
    function up() {
        addRecord(
            table = "roles",
            id = 1,
            name = "admin",
            active = true
        );
    }
    function down() {
        removeRecord(table = "roles", where = "id = 1");
    }
}

addReference()

Migrator Migration Functions void migration

Add a foreign key constraint to the database, using the reference name that was used to create it Only available in a migration CFC

Name Type Required Default Description
table string Yes The table name to perform the operation on
referenceName string No The reference table name to perform the operation on
columnName string No Alias for referenceName (consistent with the modern migrator surface — columnName / columnNames are accepted alongside the legacy form).
columnNames string No Plural alias for referenceName. When both columnName and columnNames are supplied, columnNames wins.
// 1. Add a foreign key from comments.postId to posts.id using a reference name
// Equivalent to: addForeignKey(table="comments", referenceTable="posts", column="postId", referenceColumn="id")
addReference(table="comments", referenceName="post");

// 2. Add a foreign key from order_items.orderId to orders.id
addReference(table="order_items", referenceName="order");

// 3. Use addReference in a migration's up() and undo it with dropReference() in down()
// In your migration CFC:
//
// public void function up() {
//     addReference(table="comments", referenceName="post");
// }
//
// public void function down() {
//     dropReference(table="comments", referenceName="post");
// }

afterCreate()

Model Configuration Callback Functions void model

Registers method(s) that should be called after a new object is created.

Name Type Required Default Description
methods string No Method name or list of method names that should be called when this callback event occurs in an object's life cycle (can also be called with the method argument).
// 1. Register a single method to run after an object is created
// In models/User.cfc
component extends="Model" {
    function config() {
        afterCreate("sendWelcomeEmail");
    }
    private function sendWelcomeEmail() {
        // send email to this.email
    }
}

// 2. Register multiple methods by passing a comma-delimited list
afterCreate("updateCache,notifyAdmin");

// 3. Register using the named `methods` argument
afterCreate(methods="syncToExternalApi");

afterDelete()

Model Configuration Callback Functions void model

Registers method(s) that should be called after an object is deleted.

Name Type Required Default Description
methods string No Method name or list of method names that should be called when this callback event occurs in an object's life cycle (can also be called with the method argument).
// 1. Call a single method after an object is deleted
// In models/Order.cfc
afterDelete("notifyWarehouse");

// 2. Call multiple methods after an object is deleted (comma-separated list)
// In models/User.cfc
afterDelete("removeFromSearchIndex,clearCachedData");

// 3. Register several after-delete callbacks individually for clarity
// In models/Article.cfc
afterDelete("logDeletion");
afterDelete("cleanupAttachments");

afterFind()

Model Configuration Callback Functions void model

Registers method(s) that should be called after an existing object has been initialized (which is usually done with the findByKey or findOne method).

Name Type Required Default Description
methods string No Method name or list of method names that should be called when this callback event occurs in an object's life cycle (can also be called with the method argument).
// 1. Register a single callback method to run after records are fetched
// In models/User.cfc
config() {
	afterFind("setFetchedAt");
}

// The callback receives each row's columns as arguments; return the struct to modify the record.
function setFetchedAt() {
	arguments.fetchedAt = Now();
	return arguments;
}

// 2. Format a column value after a find (works for both query rows and objects)
// In models/Product.cfc
config() {
	afterFind("formatPrice");
}

function formatPrice() {
	if (StructKeyExists(arguments, "price")) {
		arguments.price = DollarFormat(arguments.price);
	}
	return arguments;
}

// 3. Register multiple callback methods as a comma-delimited list
config() {
	afterFind("setFetchedAt,formatPrice");
}

afterInitialization()

Model Configuration Callback Functions void model

Registers method(s) that should be called after an object has been initialized.

Name Type Required Default Description
methods string No Method name or list of method names that should be called when this callback event occurs in an object's life cycle (can also be called with the method argument).
// 1. Call a single method after any object is initialized (whether new or fetched from the database)
afterInitialization("fixObj");

// 2. Call multiple methods after initialization by passing a comma-delimited list
afterInitialization("setDefaults,fixObj");

afterNew()

Model Configuration Callback Functions void model

Registers method(s) that should be called after a new object has been initialized (which is usually done with the new method).

Name Type Required Default Description
methods string No Method name or list of method names that should be called when this callback event occurs in an object's life cycle (can also be called with the method argument).
// 1. Call a single method after a new object is initialized
// In models/User.cfc
component extends="Model" {
    function config() {
        afterNew("setDefaults");
    }
    private function setDefaults() {
        this.role = "member";
        this.active = true;
    }
}

// 2. Call multiple methods after a new object is initialized (comma-delimited list)
afterNew("setDefaults,generateToken");

// 3. Use the `method` argument alias instead of `methods`
afterNew(method="setDefaults");

afterSave()

Model Configuration Callback Functions void model

Registers method(s) that should be called after an object is saved.

Name Type Required Default Description
methods string No Method name or list of method names that should be called when this callback event occurs in an object's life cycle (can also be called with the method argument).
// 1. Register a single callback method to run after an object is saved (both create and update)
// In models/User.cfc
component extends="Model" {
    function config() {
        afterSave("sendWelcomeEmail");
    }

    private function sendWelcomeEmail() {
        // called automatically each time a User is saved
    }
}

// 2. Register multiple callback methods using a comma-delimited list
component extends="Model" {
    function config() {
        afterSave("updateSearchIndex,notifyAdmins");
    }
}

// 3. Register multiple callbacks by calling afterSave() more than once
component extends="Model" {
    function config() {
        afterSave("updateSearchIndex");
        afterSave("notifyAdmins");
    }
}

afterUpdate()

Model Configuration Callback Functions void model

Registers method(s) that should be called after an existing object is updated.

Name Type Required Default Description
methods string No Method name or list of method names that should be called when this callback event occurs in an object's life cycle (can also be called with the method argument).
// 1. Register a single method to run after an object is updated
// In models/User.cfc
component extends="Model" {
    function config() {
        afterUpdate("clearCache");
    }
    private function clearCache() {
        // invalidate cached data for this user
    }
}

// 2. Register multiple methods by passing a comma-delimited list
afterUpdate("clearCache,notifyAuditLog");

// 3. Register using the named `methods` argument
afterUpdate(methods="syncToSearchIndex");

afterValidation()

Model Configuration Callback Functions void model

Registers method(s) that should be called after an object is validated.

Name Type Required Default Description
methods string No Method name or list of method names that should be called when this callback event occurs in an object's life cycle (can also be called with the method argument).
// 1. Call a single method after an object is validated
afterValidation("fixObj");

// 2. Call multiple methods after an object is validated (comma-delimited list)
afterValidation("sanitizeFields,logValidationResult");

// 3. Use the singular `method` alias for clarity
afterValidation(method="trimWhitespace");

afterValidationOnCreate()

Model Configuration Callback Functions void model

Registers method(s) that should be called after a new object is validated.

Name Type Required Default Description
methods string No Method name or list of method names that should be called when this callback event occurs in an object's life cycle (can also be called with the method argument).
// 1. Call a single method after a new object is validated on create
component extends="Model" {
	function config() {
		afterValidationOnCreate("assignDefaults");
	}

	private function assignDefaults() {
		if (!Len(this.role)) {
			this.role = "member";
		}
	}
}

// 2. Call multiple methods after validation on create (comma-delimited list)
component extends="Model" {
	function config() {
		afterValidationOnCreate("sanitizeFields,logNewRecord");
	}
}

// 3. Use the singular `method` alias for clarity
component extends="Model" {
	function config() {
		afterValidationOnCreate(method="trimWhitespace");
	}
}

afterValidationOnUpdate()

Model Configuration Callback Functions void model

Registers method(s) that should be called after an existing object is validated.

Name Type Required Default Description
methods string No Method name or list of method names that should be called when this callback event occurs in an object's life cycle (can also be called with the method argument).
// 1. Call a single method after an existing object is validated on update
// In models/User.cfc:
component extends="Model" {
    function config() {
        afterValidationOnUpdate("stampUpdatedBy");
    }

    private function stampUpdatedBy() {
        this.updatedBy = request.currentUserId;
    }
}

// 2. Register multiple methods to run after an existing object is validated on update
component extends="Model" {
    function config() {
        afterValidationOnUpdate("normalizeSlug,logValidation");
    }

    private function normalizeSlug() {
        this.slug = LCase(Replace(this.title, " ", "-", "all"));
    }

    private function logValidation() {
        // custom logging logic here
    }
}

allAssociationErrors()

Model Object Error Functions array model

Gets all associated errors recursively

Name Type Required Default Description
seenErrors array No [runtime expression]
// 1. Collect all validation errors from associated objects on a post
post = model("Post").findOne(where="id=1", include="comments");
errors = post.allAssociationErrors();
// errors -> array of error structs from associated comments (and their associations, recursively)
// Each struct contains keys: property, message, name

// 2. Use allErrors() with includeAssociations=true instead (preferred shorthand)
// allErrors() calls allAssociationErrors() internally when includeAssociations is true
post = model("Post").findOne(where="id=1", include="comments");
allErrors = post.allErrors(includeAssociations=true);
// allErrors -> combined array of the post's own errors plus all associated errors

// 3. Check if any associated model has errors before saving
order = model("Order").findOne(where="id=1", include="lineItems");
associationErrors = order.allAssociationErrors();
if (arrayLen(associationErrors)) {
    writeOutput("One or more line items have validation errors.");
}

allChanges()

Model Object Change Functions struct model

Returns a struct detailing all changes that have been made on the object but not yet saved to the database.

// 1. Get an object, change some properties, and inspect all changes before saving
member = model("member").findByKey(params.memberId);
member.firstName = params.newFirstName;
member.email = params.newEmail;
changes = member.allChanges();
// changes -> {
//   firstName: { changedFrom: "Jane", changedTo: "Janet" },
//   email:     { changedFrom: "jane@example.com", changedTo: "janet@example.com" }
// }

// 2. Only call allChanges() when there are changes to process
post = model("post").findByKey(params.id);
post.title = params.title;
post.body = params.body;
if (post.hasChanged()) {
    changes = post.allChanges();
    for (prop in changes) {
        writeOutput("'#prop#' changed from '#changes[prop].changedFrom#' to '#changes[prop].changedTo#'");
    }
}

// 3. allChanges() returns an empty struct when nothing has changed
user = model("user").findByKey(params.userId);
changes = user.allChanges();
// changes -> {} (empty struct — no unsaved changes)

allErrors()

Model Object Error Functions array model

Returns an array of all the errors on the object. It does this by storing instances of models that are associations, and not checking associations of those instances because they have already been checked.

Name Type Required Default Description
includeAssociations boolean No false
seenErrors array No [runtime expression] is a private argument not meant to be used by the user, the function uses this to ensure circular dependency avoidance.
// 1. Get all errors on a model object after a failed validation
user = model("User").new(username="", password="");
user.valid();
errors = user.allErrors();
// errors ->
// [
//   { message: "Username must not be blank.", name: "", property: "username" },
//   { message: "Password must not be blank.", name: "", property: "password" }
// ]

// 2. Check for errors and iterate over them
if (user.hasErrors()) {
	for (error in user.allErrors()) {
		writeOutput(error.property & ": " & error.message);
	}
}

// 3. Include errors from associated models (e.g. a user with associated profile)
user = model("User").findOne(where="id=1", include="profile");
user.valid();
allErrors = user.allErrors(includeAssociations=true);
// allErrors contains errors from both user and its associated profile model

announce()

Migrator Migration Functions any migration tabledefinition

Used internally by Migrator to provide feedback to the GUI and CLI about completed DB operations Only available in a migration CFC

Name Type Required Default Description
message string Yes
// 1. Log a custom message during a migration's up() step
function up() {
	var state = {};
	transaction {
		try {
			t = createTable(name="articles", force=true);
			t.string(columnNames="title", allowNull=false);
			t.text(columnNames="body");
			t.timestamps();
			t.create();
			announce("Created articles table");
		} catch (any e) {
			state.exception = e;
		}

		if (StructKeyExists(state, "exception")) {
			transaction action="rollback";
			throw(errorCode="1", detail=state.exception.detail, message=state.exception.message, type="any");
		} else {
			transaction action="commit";
		}
	}
}

// 2. Announce multiple steps to provide granular feedback
function up() {
	var state = {};
	transaction {
		try {
			addColumn(table="users", columnType="string", columnName="apiKey", limit=64, allowNull=true);
			announce("Added apiKey column to users");

			addIndex(table="users", columnNames="apiKey", unique=true);
			announce("Added unique index on users.apiKey");
		} catch (any e) {
			state.exception = e;
		}

		if (StructKeyExists(state, "exception")) {
			transaction action="rollback";
			throw(errorCode="1", detail=state.exception.detail, message=state.exception.message, type="any");
		} else {
			transaction action="commit";
		}
	}
}

api()

Configuration Routing struct mapper

Scope routes under an API path prefix. Shorthand for .group(path="api", name="api", ...). Typically used in combination with version() to organize versioned API endpoints.

Name Type Required Default Description
path string No api URL path prefix for the API. Defaults to "api".
name string No api Name prefix for route names. Defaults to "api".
constraints struct No Variable patterns to apply to all child routes.
callback any No A callback function to define nested routes within this API scope.
<cfscript>

// 1. Basic API scope using the default path and name prefix "api"
mapper()
    .api()
        // Route name:  apiUsers
        // Example URL: /api/users
        .resources("users")
    .end()
.end();

// 2. Combine api() with version() for versioned API endpoints
mapper()
    .api()
        .version(1)
            // Route name:  apiV1Users
            // Example URL: /api/v1/users
            .resources("users")
        .end()

        .version(2)
            // Route name:  apiV2Products
            // Example URL: /api/v2/products
            .resources("products")
        .end()
    .end()
.end();

// 3. Override the default path and name prefixes
mapper()
    .api(path="public-api", name="publicApi")
        // Route name:  publicApiOrders
        // Example URL: /public-api/orders
        .resources("orders")
    .end()
.end();

// 4. Use api() with a callback to avoid manual .end() calls
mapper()
    .api(callback=function(m) {
        m.version(number=1, callback=function(m) {
            // Route name:  apiV1Users
            // Example URL: /api/v1/users
            m.resources("users");
        });
    })
.end();

</cfscript>

associationInfo()

Model Class Miscellaneous Functions struct model

Returns a struct containing all association definitions for this model. Each key is the association name, and the value is a struct with association metadata including type (belongsTo, hasMany, hasOne), modelName, foreignKey, joinKey, and dependent.

// 1. Get all association definitions for a model and inspect them
info = model("post").associationInfo();
// info is a struct where each key is an association name, e.g.:
// info.comments.type        -> "hasMany"
// info.comments.modelName   -> "Comment"
// info.comments.foreignKey  -> "postId"
// info.comments.dependent   -> "delete"
// info.author.type          -> "belongsTo"
// info.author.modelName     -> "Author"

// 2. Check whether a specific association is defined on the model
info = model("user").associationInfo();
if (structKeyExists(info, "profile")) {
    writeOutput("User has a profile association of type: " & info.profile.type);
}

// 3. Iterate over all associations to build a summary
info = model("article").associationInfo();
for (assocName in info) {
    writeOutput(assocName & " -> " & info[assocName].type & " " & info[assocName].modelName);
}

associationNames()

Model Class Miscellaneous Functions string model

Returns a list of association names defined on this model.

// 1. Get all association names defined on a model
names = model("User").associationNames();
// names -> "profile,posts,comments"

// 2. Check whether a specific association exists on the model
if (listFindNoCase(model("Post").associationNames(), "comments")) {
    // the Post model has a "comments" association
}

// 3. Iterate over each association name
for (assocName in listToArray(model("Order").associationNames())) {
    writeOutput(assocName);
}

authenticityToken()

Controller Miscellaneous Functions string controller

Returns the raw CSRF authenticity token

// 1. Embed the CSRF token in a manually-built form hidden field
token = authenticityToken();
writeOutput('<input type="hidden" name="authenticityToken" value="' & token & '">');

// 2. Pass the token as a request header for an AJAX call (e.g. in a JavaScript data island)
writeOutput('<meta name="csrf-token" content="' & authenticityToken() & '">');
// JavaScript can then read this and send it as the X-CSRF-Token header with each POST request.

// 3. Include the token in a JSON API response body so a client can replay it
tokenValue = authenticityToken();
writeOutput(serializeJSON({authenticityToken = tokenValue}));

authenticityTokenField()

View Helpers General Form Functions string controller

Returns a hidden form field containing a new authenticity token.

// 1. Include CSRF token in a plain HTML form that POSTs data
//    (use this when you are not using startFormTag())
<form action="#urlFor(route='posts')#" method="post">
  #authenticityTokenField()#
  <!--- other fields here --->
</form>

// 2. Not needed for GET forms — GET requests are not CSRF-protected
<form action="#urlFor(route='posts')#" method="get">
  <!--- no token required --->
</form>

authorize()

Controller Authorization Functions any controller

Authorizes the current user for an action on a record by dispatching to the record's policy (app/policies/Policy.cfc). Throws Wheels.NotAuthorized (HTTP 403) when the policy denies, and returns the record unchanged when it allows so the call can be inlined: function update() { post = authorize(model("Post").findByKey(params.key)); post.update(params.post); } A missing policy class throws Wheels.Policy.NotDefined in development and testing (loud, Pundit-style, to catch typos) and silently denies in production — the same environment posture as tableName() (##3079). A policy class that lacks a method for the action denies.

Name Type Required Default Description
record any Yes The model instance (or model class / model name string) to authorize against.
action string No The policy method to dispatch. Defaults to the current params.action, resolved at call time.

automaticValidations()

Model Configuration Validation Functions void model

Whether or not to enable default validations for this model.

Name Type Required Default Description
value boolean Yes Set to true or false.
// 1. Disable automatic validations for this model (useful when automatic validations are enabled globally but you want to opt out for a specific model).
component extends="Model" {
	function config() {
		automaticValidations(false);
	}
}

// 2. Explicitly enable automatic validations for this model (useful when automatic validations are disabled globally but you want to opt in for a specific model).
component extends="Model" {
	function config() {
		automaticValidations(true);
	}
}

average()

Model Class Statistics Functions any model

Calculates the average value for a given property. Uses the SQL function AVG. If no records can be found to perform the calculation on you can use the ifNull argument to decide what should be returned.

Name Type Required Default Description
property string Yes Name of the property to calculate the average for.
where string No Maps to the WHERE clause of the query (or HAVING when necessary). The following operators are supported: =, !=, <>, <, <=, >, >=, LIKE, NOT LIKE, IN, NOT IN, IS NULL, IS NOT NULL, AND, and OR (note that the key words need to be written in upper case). You can also use parentheses to group statements. Nested queries not allowed. You do not need to specify the table name(s); Wheels will do that for you.
include string No Associations that should be included in the query using INNER or LEFT OUTER joins (which join type that is used depends on how the association has been set up in your model). If all included associations are set on the current model, you can specify them in a list (e.g. department,addresses,emails). You can build more complex include strings by using parentheses when the association is set on an included model, like album(artist(genre)), for example. These complex include strings only work when returnAs is set to query though.
distinct boolean No false When true, AVG will be performed only on each unique instance of a value, regardless of how many times the value occurs.
parameterize any No true Set to true to use cfqueryparam on all columns, or pass in a list of property names to use cfqueryparam on those only.
ifNull any No The value returned if no records are found. Common usage is to set this to 0 to make sure a numeric value is always returned instead of a blank string.
includeSoftDeletes boolean No false Set to true to include soft-deleted records in the queries that this method runs.
group string No Maps to the GROUP BY clause of the query. You do not need to specify the table name(s); Wheels will do that for you.
// 1. Get the average salary for all employees.
avgSalary = model("employee").average("salary");

// 2. Get the average salary for employees in a given department.
avgSalary = model("employee").average(property="salary", where="departmentId=#params.key#");

// 3. Make sure a numeric value is always returned if no records are found.
avgSalary = model("employee").average(property="salary", where="salary BETWEEN #params.min# AND #params.max#", ifNull=0);

// 4. Average only distinct salary values (duplicates excluded).
avgSalary = model("employee").average(property="salary", distinct=true);

// 5. Get the average salary grouped by department (returns a query).
avgByDept = model("employee").average(property="salary", group="departmentId");

badgeClass()

string controller

Classe Bootstrap d'une valeur de reference. La couleur vient desormais de l'API, qui la tient du referentiel. Le helper ne fait plus que l'habiller — il ne DEDUIT plus rien d'un libelle, ce qui obligeait a maintenir la correspondance en double.

Name Type Required Default Description
valeur any No [runtime expression]

beforeCreate()

Model Configuration Callback Functions void model

Registers method(s) that should be called before a new object is created.

Name Type Required Default Description
methods string No Method name or list of method names that should be called when this callback event occurs in an object's life cycle (can also be called with the method argument).
// 1. Register a single callback method to run before a new object is created
// Defined inside the model's config() function
beforeCreate("setDefaults");

// 2. Register multiple callback methods to run in sequence before creation
beforeCreate("generateSlug,stampCreatedBy");

// 3. Register callbacks using the named argument
beforeCreate(methods="generateToken,normalizeEmail");

beforeDelete()

Model Configuration Callback Functions void model

Registers method(s) that should be called before an object is deleted.

Name Type Required Default Description
methods string No Method name or list of method names that should be called when this callback event occurs in an object's life cycle (can also be called with the method argument).
// 1. Register a single method to run before an object is deleted
// In models/Post.cfc
component extends="Model" {
    function config() {
        beforeDelete("cleanUpAttachments");
    }

    private function cleanUpAttachments() {
        // Remove associated files from disk before the record is deleted
        fileDelete(expandPath("/uploads/#this.id#"));
    }
}

// 2. Register multiple methods to run before deletion (comma-delimited list)
// In models/User.cfc
component extends="Model" {
    function config() {
        beforeDelete("revokeTokens,archiveActivity");
    }

    private function revokeTokens() {
        model("Token").deleteAll(where="userId=#this.id#");
    }

    private function archiveActivity() {
        model("ActivityLog").updateAll(
            properties="archivedAt=NOW()",
            where="userId=#this.id#"
        );
    }
}

// 3. Halt deletion by returning false from the callback
// In models/Order.cfc
component extends="Model" {
    function config() {
        beforeDelete("preventIfShipped");
    }

    private function preventIfShipped() {
        // Returning false cancels the delete operation
        if (this.status eq "shipped") {
            return false;
        }
    }
}

beforeSave()

Model Configuration Callback Functions void model

Registers method(s) that should be called before an object is saved.

Name Type Required Default Description
methods string No Method name or list of method names that should be called when this callback event occurs in an object's life cycle (can also be called with the method argument).
// 1. Call a single method before every save (create or update)
// In models/User.cfc
component extends="Model" {
    function config() {
        beforeSave("normalizeEmail");
    }

    private function normalizeEmail() {
        this.email = LCase(Trim(this.email));
    }
}

// 2. Register multiple callback methods as a comma-delimited list
component extends="Model" {
    function config() {
        beforeSave("stripWhitespace,generateSlug");
    }
}

// 3. Use the `method` argument alias to register a single callback
component extends="Model" {
    function config() {
        beforeSave(method="sanitizeContent");
    }
}

beforeUpdate()

Model Configuration Callback Functions void model

Registers method(s) that should be called before an existing object is updated.

Name Type Required Default Description
methods string No Method name or list of method names that should be called when this callback event occurs in an object's life cycle (can also be called with the method argument).
// 1. Call a single method before every update
// In models/User.cfc
component extends="Model" {
    function config() {
        beforeUpdate("stampUpdatedBy");
    }

    private function stampUpdatedBy() {
        this.updatedBy = session.userId;
    }
}

// 2. Register multiple callback methods as a comma-delimited list
component extends="Model" {
    function config() {
        beforeUpdate("validateOwnership,recalculateTotals");
    }
}

// 3. Use the `method` argument alias to register a single callback
component extends="Model" {
    function config() {
        beforeUpdate(method="fixObj");
    }
}

beforeValidation()

Model Configuration Callback Functions void model

Registers method(s) that should be called before an object is validated.

Name Type Required Default Description
methods string No Method name or list of method names that should be called when this callback event occurs in an object's life cycle (can also be called with the method argument).
// 1. Register a single method to run before any validation
// In models/User.cfc
component extends="Model" {
    function config() {
        beforeValidation("normalizeEmail");
        validatesPresenceOf("email");
    }

    private function normalizeEmail() {
        this.email = LCase(Trim(this.email));
    }
}

// 2. Register multiple methods to run before validation using a comma-delimited list
// In models/Article.cfc
component extends="Model" {
    function config() {
        beforeValidation("stripTags,setSlug");
        validatesPresenceOf(properties="title,slug");
    }

    private function stripTags() {
        this.title = ReReplace(this.title, "<[^>]*>", "", "all");
    }

    private function setSlug() {
        if (!Len(this.slug)) {
            this.slug = LCase(ReReplace(Trim(this.title), "\s+", "-", "all"));
        }
    }
}

// 3. Register callbacks across multiple calls (they are stacked in order)
// In models/Product.cfc
component extends="Model" {
    function config() {
        beforeValidation("trimFields");
        beforeValidation("setDefaults");
    }

    private function trimFields() {
        this.name = Trim(this.name);
    }

    private function setDefaults() {
        if (!Len(this.status)) {
            this.status = "draft";
        }
    }
}

beforeValidationOnCreate()

Model Configuration Callback Functions void model

Registers method(s) that should be called before a new object is validated.

Name Type Required Default Description
methods string No Method name or list of method names that should be called when this callback event occurs in an object's life cycle (can also be called with the method argument).
// 1. Register a single method to run before a new object is validated
// In models/User.cfc config()
beforeValidationOnCreate("sanitizeEmail");

// 2. Register multiple methods to run before a new object is validated
// In models/Order.cfc config()
beforeValidationOnCreate("setDefaultStatus,generateTrackingNumber");

// 3. Use the `method` argument alias instead of `methods`
// In models/Post.cfc config()
beforeValidationOnCreate(method="normalizeSlug");

beforeValidationOnUpdate()

Model Configuration Callback Functions void model

Registers method(s) that should be called before an existing object is validated.

Name Type Required Default Description
methods string No Method name or list of method names that should be called when this callback event occurs in an object's life cycle (can also be called with the method argument).
// 1. Register a single method to run before an existing object is validated on update
// Called inside the model's config() function
beforeValidationOnUpdate("sanitizeFields");

// 2. Register multiple methods as a comma-delimited list
beforeValidationOnUpdate("sanitizeFields,enforceBusinessRules");

// 3. Use the `method` argument alias for a single callback
beforeValidationOnUpdate(method="normalizeEmail");

belongsTo()

Model Configuration Association Functions void model

Sets up a belongsTo association between this model and the specified one. Use this association when this model contains a foreign key referencing another model.

Name Type Required Default Description
name string Yes Gives the association a name that you refer to when working with the association (in the include argument to findAll, to name one example).
modelName string No Name of associated model (usually not needed if you follow Wheels conventions because the model name will be deduced from the name argument).
foreignKey string No Foreign key property name (usually not needed if you follow Wheels conventions since the foreign key name will be deduced from the name argument).
joinKey string No Column name to join to if not the primary key (usually not needed if you follow Wheels conventions since the join key will be the table's primary key/keys).
joinType string No inner Use to set the join type when joining associated tables. Possible values are inner (for INNER JOIN) and outer (for LEFT OUTER JOIN).
polymorphic boolean No false Set to true to declare a polymorphic belongsTo association. The foreign key defaults to {name}Id and a {name}Type column is used to store the owning model name at runtime.
// 1. Specify that instances of this model belong to an author.
// (The table for this model should have a foreign key column, typically named `authorId`.)
belongsTo("author");

// 2. Override naming conventions by specifying `modelName` and `foreignKey` explicitly.
belongsTo(name="bookWriter", modelName="author", foreignKey="authorId");

// 3. Use a LEFT OUTER JOIN instead of the default INNER JOIN when including this association.
belongsTo(name="category", joinType="outer");

// 4. Declare a polymorphic belongsTo association (e.g. a Comment that can belong to a Post or a Photo).
// Wheels will look for `commentableId` and `commentableType` columns on the comments table.
belongsTo(name="commentable", polymorphic=true);

bigInteger()

Migrator Table Definition Functions any tabledefinition

Adds integer columns to table definition.

Name Type Required Default Description
columnNames string No
limit numeric No
default any No
allowNull boolean No
// 1. Add a single bigInteger column to a new table
t = createTable(name='events');
	t.bigInteger(columnNames='externalId');
	t.string(columnNames='title', limit=255, allowNull=false);
	t.timestamps();
t.create();

// 2. Add multiple bigInteger columns at once
t = createTable(name='analytics');
	t.bigInteger(columnNames='pageViews,uniqueVisitors', default=0, allowNull=false);
	t.string(columnNames='path', limit=500, allowNull=false);
	t.timestamps();
t.create();

// 3. Add a bigInteger column with a limit and default when altering an existing table
t = changeTable(name='orders');
	t.bigInteger(columnNames='totalCents', default=0, allowNull=false);
t.change();

binary()

Migrator Table Definition Functions any tabledefinition

Adds binary columns to table definition.

Name Type Required Default Description
columnNames string No
default any No
allowNull boolean No
// 1. Add a single binary column to a new table
t = createTable(name='attachments');
	t.string(columnNames='filename', limit=255, allowNull=false);
	t.binary(columnNames='fileData');
	t.timestamps();
t.create();

// 2. Add multiple binary columns at once
t = createTable(name='media');
	t.string(columnNames='title', limit=255, allowNull=false);
	t.binary(columnNames='thumbnail,fullImage', allowNull=false);
	t.timestamps();
t.create();

// 3. Add a binary column with a default when altering an existing table
t = changeTable(name='documents');
	t.binary(columnNames='rawContent', allowNull=true);
t.change();

boolean()

Migrator Table Definition Functions any tabledefinition

Adds boolean columns to table definition.

Name Type Required Default Description
columnNames string No
default any No
allowNull boolean No
// 1. Add a single boolean column to a new table
t = createTable(name='products');
	t.string(columnNames='name', limit=255, allowNull=false);
	t.boolean(columnNames='isActive', default=1, allowNull=false);
	t.timestamps();
t.create();

// 2. Add multiple boolean columns at once
t = createTable(name='users');
	t.string(columnNames='email', limit=255, allowNull=false);
	t.boolean(columnNames='isAdmin,isVerified,isActive', default=0, allowNull=false);
	t.timestamps();
t.create();

// 3. Add a boolean column to an existing table
t = changeTable(name='articles');
	t.boolean(columnNames='isPublished', default=0, allowNull=false);
t.change();

buttonTag()

View Helpers General Form Functions string controller

Builds and returns a string containing a button form control.

Name Type Required Default Description
content string No Save changes Content to display inside the button.
type string No submit The type for the button: button, reset, or submit.
value string No save The value of the button when submitted.
image string No File name of the image file to use in the button form control.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic submit button inside a form
#startFormTag(action="create")#
    #buttonTag(content="Save changes", value="save")#
#endFormTag()#
<!--- Produces: <button type="submit" value="save">Save changes</button> --->

// 2. Reset button to clear form fields
#buttonTag(content="Clear form", type="reset")#
<!--- Produces: <button type="reset" value="save">Clear form</button> --->

// 3. Plain button (no form submission) with a CSS class and id
#buttonTag(content="Open dialog", type="button", value="open", class="btn btn-secondary", id="openDialogBtn")#
<!--- Produces: <button type="button" value="open" class="btn btn-secondary" id="openDialogBtn">Open dialog</button> --->

// 4. Submit button wrapped in a paragraph using prepend and append
#buttonTag(content="Submit", value="submit", prepend="<p>", append="</p>")#
<!--- Produces: <p><button type="submit" value="submit">Submit</button></p> --->

// 5. Image button (renders an img tag inside the button element)
#buttonTag(content="", image="submit-icon.png", value="save")#
<!--- Produces: <button type="submit" value="save"><img src="/images/submit-icon.png" alt="Submit Icon" /></button> --->

buttonTo()

View Helpers Link Functions string controller

Creates a form containing a single button that submits to the URL. Note: Pass any additional arguments by prefixing them with "input" like inputClass, inputRel, and inputId, and the generated tag will also include those values as HTML attributes. The URL is built the same way as the linkTo function.

Name Type Required Default Description
text string No The text content of the button.
image string No If you want to use an image for the button pass in the link to it here (relative from the images folder).
route string No Name of a route that you have configured in config/routes.cfm.
controller string No Name of the controller to include in the URL.
action string No Name of the action to include in the URL.
key any No Key(s) to include in the URL.
params string No Any additional parameters to be set in the query string (example: wheels=cool&x=y). Please note that Wheels uses the & and = characters to split the parameters and encode them properly for you. However, if you need to pass in & or = as part of the value, then you need to encode them (and only them), example: a=cats%26dogs%3Dtrouble!&b=1.
anchor string No Sets an anchor name to be appended to the path.
method string No The type of method to use in the form tag (delete, get, patch, post, and put are the options).
onlyPath boolean No true If true, returns only the relative URL (no protocol, host name or port).
host string No Set this to override the current host.
protocol string No Set this to override the current protocol.
port numeric No 0 Set this to override the current port number.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic button that submits to a controller/action
#buttonTo(text="Delete Account", controller="account", action="delete")#
<!--- Outputs: <form action="/account/delete" method="post"><button type="submit">Delete Account</button></form> --->

// 2. If you're already in the `account` controller, CFWheels will assume the current controller
#buttonTo(text="Delete Account", action="delete")#
<!--- Outputs: <form action="/account/delete" method="post"><button type="submit">Delete Account</button></form> --->

// 3. Use `method` to send a DELETE request (a hidden `_method` field is added automatically)
#buttonTo(text="Remove Post", controller="blog", action="delete", key=99, method="delete")#
<!--- Outputs: <form action="/blog/delete/99" method="post"><input type="hidden" name="_method" value="delete" /><button type="submit">Remove Post</button></form> --->

// 4. Use a named route configured in `config/routes.cfm`
#buttonTo(text="Archive", route="archivePost", postId=12)#

// 5. Show a "please wait" state by disabling the button on click — pass extra attributes to the button using the `input` prefix
#buttonTo(text="Place Order", action="checkout", inputId="checkout-btn", inputClass="btn btn-primary", inputData-disable-with="Processing...")#

// 6. Use an image instead of text for the button
#buttonTo(image="icons/trash.png", action="destroy", key=params.id, method="delete")#

caches()

Controller Configuration Functions void controller

Tells Wheels to cache one or more actions.

Name Type Required Default Description
action string No Action(s) to cache. This argument is also aliased as actions.
time numeric No 60 Minutes to cache the action(s) for.
static boolean No false Set to true to tell Wheels that this is a static page and that it can skip running the controller filters (before and after filters set on actions). Please note that the onSessionStart and onRequestStart events still execute though.
appendToKey string No List of variables to be evaluated at runtime and included in the cache key so that content can be cached separately.
// 1. Cache the `termsOfUse` action for the default 60 minutes.
caches("termsOfUse");

// 2. Cache two actions for 30 minutes.
caches(actions="browseByUser,browseByTitle", time=30);

// 3. Cache the `termsOfUse` and `codeOfConduct` actions, including their filters.
caches(actions="termsOfUse,codeOfConduct", static=true);

// 4. Cache content separately based on region.
caches(action="home", appendToKey="request.region");

callbackInfo()

Model Class Miscellaneous Functions struct model

Returns a struct containing all callback definitions for this model, keyed by callback type (e.g., beforeSave, afterCreate). Each callback type contains an array of callback method names.

// 1. Inspect all registered callbacks for a model
info = model("Order").callbackInfo();
// info is a struct keyed by callback type, each containing an array of method names:
// {
//   beforeSave:               ["stampUpdatedAt"],
//   afterCreate:              ["sendConfirmationEmail"],
//   afterSave:                ["clearCacheEntries"],
//   beforeValidation:         [],
//   beforeValidationOnCreate: [],
//   afterValidation:          [],
//   afterFind:                [],
//   ...
// }

// 2. Check whether a specific callback type has any registered methods
info = model("User").callbackInfo();
if (arrayLen(info.beforeDelete)) {
    writeOutput("User model has beforeDelete callbacks.");
}

// 3. Loop over all callback types and their methods for debugging
info = model("Post").callbackInfo();
for (callbackType in info) {
    for (methodName in info[callbackType]) {
        writeOutput(callbackType & ": " & methodName);
    }
}

can()

Controller Authorization Functions boolean controller

Non-throwing boolean policy check for conditionals and views (views run in the controller's variables scope, so can() is available in templates automatically): ##linkTo(text="Edit", route="editPost", key=post.id)## Returns false (deny) for a guest, for an empty record, and for actions the policy has no method for. A missing policy class still throws Wheels.Policy.NotDefined in development/testing so typos fail loud; in production it returns false.

Name Type Required Default Description
action string Yes The policy method to check.
record any No The model instance (or model class / model name string) to check against. Empty string denies.

capitalize()

Global Helpers String Functions string controller model mapper migrator migration tabledefinition

Capitalizes the first character of the supplied string.

Name Type Required Default Description
text string Yes String to capitalize.
// 1. Capitalize the first character of a sentence
result = capitalize("wheels is a framework");
// result -> "Wheels is a framework"

// 2. Capitalize a lowercase word
result = capitalize("hello");
// result -> "Hello"

// 3. Returns an already-capitalized string unchanged
result = capitalize("CFWheels");
// result -> "CFWheels"

change()

Migrator Table Definition Functions void tabledefinition

alters existing table in the database

Name Type Required Default Description
addColumns boolean No false
// 1. Alter existing columns on a table (default behavior — modifies columns that already exist)
t = changeTable(name='users');
	t.string(columnNames='email', limit=255, allowNull=false);
	t.boolean(columnNames='active', default=true, allowNull=false);
t.change();

// 2. Add new columns to an existing table using addColumns=true
t = changeTable(name='products');
	t.string(columnNames='sku', limit=100, allowNull=false);
	t.decimal(columnNames='discountPrice', precision=10, scale=2, allowNull=true);
t.change(addColumns=true);

// 3. Add a foreign key reference column to an existing table
t = changeTable(name='orders');
	t.references(columnNames='customer', allowNull=false);
t.change(addColumns=true);

changeColumn()

Migrator Migration Functions void migration

changes a column definition Only available in a migration CFC

Name Type Required Default Description
table string Yes The Name of the table where the column is
columnName string No The name of the column
columnNames string No Modern alias for columnName (matches the plural form every TableDefinition column helper accepts). Pass one or the other — not both.
columnType string Yes The type of the column
afterColumn string No The name of the column which this column should be inserted after
referenceName string No Name for reference column, see documentation for references function, required if columnType is 'reference'
default any No Default value for this column
allowNull boolean No Whether to allow NULL values
limit numeric No Character or integer size limit for column
precision numeric No (For decimal type) the maximum number of digits allow
scale numeric No (For decimal type) the number of digits to the right of the decimal point
addColumns boolean No false if true, attempts to add columns and database will likely throw an error if column already exists
// 1. Change a string column's length limit
changeColumn(table="members", columnName="status", columnType="string", limit=50);

// 2. Change a column type and set a default value
changeColumn(table="orders", columnName="quantity", columnType="integer", default=1);

// 3. Change a decimal column with precision and scale
changeColumn(table="products", columnName="price", columnType="decimal", precision=10, scale=2, allowNull=false);

// 4. Change a text column and explicitly allow NULL values
changeColumn(table="articles", columnName="summary", columnType="text", allowNull=true);

changedFrom()

Model Object Change Functions string model

Returns the previous value of a property that has changed. Returns an empty string if no previous value exists. Wheels will keep a note of the previous property value until the object is saved to the database.

Name Type Required Default Description
property string Yes Name of property to get the previous value for.
// 1. Get the previous value of a changed property
user = model("User").findByKey(params.userId);
user.email = params.newEmail;

// Returns the original email address before it was changed
oldEmail = user.changedFrom("email");
// oldEmail -> "original@example.com"

// 2. Use the dynamic shorthand method (equivalent to the above)
oldEmail = user.emailChangedFrom();

// 3. Check if a property changed before accessing the previous value
user = model("User").findByKey(params.userId);
user.firstName = params.firstName;

if (user.hasChanged("firstName")) {
	oldName = user.changedFrom("firstName");
	// oldName -> "Jane"
}
// Returns empty string if property has not changed or no previous value exists

changedProperties()

Model Object Change Functions string model

Returns a list of the object properties that have been changed but not yet saved to the database.

// 1. Find a member, change some properties, then inspect which ones have changed
member = model("member").findByKey(params.memberId);
member.firstName = params.newFirstName;
member.email = params.newEmail;
changed = member.changedProperties();
// changed -> "firstName,email"

// 2. Only save when there are actually unsaved changes
user = model("User").findByKey(params.userId);
user.lastName = params.lastName;
if (Len(user.changedProperties())) {
    user.save();
}

// 3. Use changedProperties() alongside changedFrom() to build an audit log entry
post = model("Post").findByKey(params.postId);
post.title = params.title;
post.body = params.body;
changedList = post.changedProperties();
for (prop in ListToArray(changedList)) {
    writeOutput("Property '#prop#' was '#post.changedFrom(prop)#', now '#post[prop]#'.");
}

changeTable()

Migrator Migration Functions TableDefinition migration

Creates a table definition object to store modifications to table properties Only available in a migration CFC

Name Type Required Default Description
name string Yes Name of the table to set change properties on
// 1. Add a new string column to an existing table
t = changeTable(name="employees");
t.string(columnNames="fullName", default="", allowNull=true, limit=255);
t.change();

// 2. Modify multiple columns at once (change type and nullability)
t = changeTable(name="products");
t.integer(columnNames="stock", default=0, allowNull=false);
t.boolean(columnNames="active", default=true, allowNull=false);
t.change();

// 3. Add a new column using addColumns=true so the migration fails gracefully if the column already exists
t = changeTable(name="orders");
t.datetime(columnNames="shippedAt", allowNull=true);
t.change(addColumns=true);

channelSSETag()

string controller

Generate a 'script' tag that creates an EventSource for a channel. Convenience view helper for quickly wiring up SSE in templates.

Name Type Required Default Description
channel string Yes The channel name.
route string No Named route for the SSE endpoint.
controller string No Controller name (used with action if no route).
action string No stream Action name (default "stream").
events string No Comma-delimited list of event types.

char()

Migrator Table Definition Functions any tabledefinition

adds char columns to table definition

Name Type Required Default Description
columnNames string No
limit any No
default any No
allowNull boolean No
// 1. Add a single char column to a new table
t = createTable(name='countries');
	t.char(columnNames='code', limit=2, allowNull=false);
	t.string(columnNames='name', limit=100, allowNull=false);
	t.timestamps();
t.create();

// 2. Add multiple char columns at once
t = createTable(name='products');
	t.char(columnNames='sku,barcode', limit=12, allowNull=false);
	t.string(columnNames='title', limit=255, allowNull=false);
	t.timestamps();
t.create();

// 3. Add a char column with a default value when altering an existing table
t = changeTable(name='orders');
	t.char(columnNames='statusCode', limit=1, default='N', allowNull=false);
t.change();

checkBox()

View Helpers Form Object Functions string controller

Builds and returns a string containing a check box form control based on the supplied name. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
objectName any Yes The variable name of the object to build the form control for.
property string Yes The name of the property to use in the form control.
association string No The name of the association that the property is located on. Used for building nested forms that work with nested properties. If you are building a form with deep nesting, simply pass in a list to the nested object, and Wheels will figure it out.
position string No The position used when referencing a hasMany relationship in the association argument. Used for building nested forms that work with nested properties. If you are building a form with deep nestings, simply pass in a list of positions, and Wheels will figure it out.
checkedValue string No 1 Value of check box in its checked state.
uncheckedValue string No 0 The value of the check box when it's on the unchecked state.
label string No useDefaultLabel The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
errorElement string No span HTML tag to wrap the form control with when the object contains errors.
errorClass string No field-with-errors The class name of the HTML tag that wraps the form control when there are errors.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic check box bound to a boolean model property
#checkBox(objectName="photo", property="isPublic", label="Display this photo publicly.")#

// 2. Custom checked and unchecked values (e.g. "yes" / "no" instead of 1 / 0)
#checkBox(objectName="user", property="agreedToTerms", checkedValue="yes", uncheckedValue="no", label="I agree to the terms of service.")#

// 3. Check boxes for a nested association (photos belonging to a user)
<cfloop from="1" to="#ArrayLen(user.photos)#" index="i">
    #checkBox(objectName="user", association="photos", position=i, property="isPublic", label="Make public: #user.photos[i].title#")#
</cfloop>

checkBoxTag()

View Helpers Form Tag Functions string controller

Builds and returns a string containing a check box form control based on the supplied name. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
name string Yes Name to populate in tag's name attribute.
checked boolean No false Whether or not the check box should be checked by default.
value string No 1 Value of check box in its checked state.
uncheckedValue string No The value of the check box when it's on the unchecked state.
label string No The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic usage with a label and a pre-checked state
<cfoutput>
	#checkBoxTag(name="subscribe", value="1", label="Subscribe to our newsletter", checked=true)#
</cfoutput>

// 2. Render an unchecked check box that also submits a value when unchecked
<cfoutput>
	#checkBoxTag(name="agreeToTerms", value="1", uncheckedValue="0", label="I agree to the terms")#
</cfoutput>

// 3. Loop over a query to render one check box per option, checking those already selected
// Controller
toppings = model("Topping").findAll(order="name");
selectedIds = "2,5,9"; // e.g. previously saved topping IDs as a comma-delimited list

// View
<cfoutput query="toppings">
	#checkBoxTag(
		name    = "toppingIds",
		value   = toppings.id,
		label   = toppings.name,
		checked = listFindNoCase(selectedIds, toppings.id) GT 0
	)#
</cfoutput>

classInfo()

Model Class Miscellaneous Functions struct model

Returns a comprehensive struct of all model metadata suitable for code generation and introspection tools. Includes model name, table name, primary keys, properties, associations, validations, enums, scopes, and callbacks.

// 1. Inspect all metadata for the User model
info = model("User").classInfo();
// info.modelName             -> "User"
// info.tableName             -> "users"
// info.primaryKeys           -> "id"
// info.propertyNames         -> "id,firstName,lastName,email,createdAt,updatedAt"
// info.properties            -> struct of column/type metadata keyed by property name
// info.calculatedProperties  -> struct of SQL-expression properties keyed by property name
// info.associations          -> struct of association definitions (belongsTo, hasMany, etc.)
// info.validations           -> struct keyed by trigger (onSave, onCreate, onUpdate) with arrays of rules
// info.enums                 -> struct of enum definitions keyed by property name
// info.scopes                -> struct of named scope definitions
// info.callbacks             -> struct of callback arrays keyed by callback type (beforeSave, afterCreate, etc.)
// info.softDeletion          -> false (true when the model has a deletedAt column)

// 2. List all association names and their types
info = model("Article").classInfo();

for (assocName in info.associations) {
    assoc = info.associations[assocName];
    writeOutput(assocName & " (" & assoc.type & ")");
}

// 3. Check soft-deletion and enumerate registered callbacks
info = model("Post").classInfo();

if (info.softDeletion) {
    writeOutput("Post uses soft deletion.");
}

for (callbackType in info.callbacks) {
    methods = info.callbacks[callbackType];
    writeOutput(callbackType & ": " & arrayToList(methods));
}

// 4. Inspect calculated properties defined on the model
info = model("Order").classInfo();

for (propName in info.calculatedProperties) {
    calcProp = info.calculatedProperties[propName];
    writeOutput(propName & " => " & calcProp.sql);
}

clearCachableActions()

Controller Configuration Functions void controller

Clears cached action metadata for current controller.

Name Type Required Default Description
action string No Optional. A single action or list of actions to clear. If not provided, clears all cached actions of current controller.
// 1. Clear all cached action metadata for the current controller.
clearCachableActions();

// 2. Clear the cached metadata for a single action.
clearCachableActions(action="termsOfUse");

// 3. Clear the cached metadata for a list of specific actions.
clearCachableActions(action="browseByUser,browseByTitle");

clearChangeInformation()

Model Object Change Functions void model

Clears all internal knowledge of the current state of the object.

Name Type Required Default Description
property string No string false Name of property to clear information for.
// 1. Clear change tracking for a single property
// Convert startTime to UTC in an afterFind callback, then tell Wheels to treat
// the converted value as the "original" so it won't be flagged as changed or
// saved unnecessarily.
this.startTime = dateConvert("Local2UTC", this.startTime);
this.clearChangeInformation(property="startTime");

// 2. Clear change tracking for all properties at once
// After manually adjusting values in an afterFind callback, reset Wheels'
// internal state so none of the touched properties appear as dirty.
this.clearChangeInformation();

// 3. Typical afterFind callback usage in a model
// In User.cfc config():
//   afterFind("normalizeTimestamps");
// The callback method:
function normalizeTimestamps() {
    if (structKeyExists(this, "createdAt")) {
        this.createdAt = dateConvert("Local2UTC", this.createdAt);
    }
    if (structKeyExists(this, "updatedAt")) {
        this.updatedAt = dateConvert("Local2UTC", this.updatedAt);
    }
    // Mark both properties as clean so hasChanged() returns false
    // and save() won't push them back to the database.
    this.clearChangeInformation(property="createdAt");
    this.clearChangeInformation(property="updatedAt");
}

clearErrors()

Model Object Error Functions void model

Clears out all errors set on the object or only the ones set for a specific property or name.

Name Type Required Default Description
property string No Specify a property name here if you want to clear all errors set on that property.
name string No Specify an error name here if you want to clear all errors set with that error name.
// 1. Clear all errors on the object
this.clearErrors();

// 2. Clear all errors set on the `firstName` property
this.clearErrors(property="firstName");

// 3. Clear only errors that were set with a specific error name
this.clearErrors(name="invalidFormat");

// 4. Clear errors on a specific property that were also set with a specific name
this.clearErrors(property="email", name="duplicateEmail");

closeSSEStream()

void controller

Close an SSE streaming connection.

Name Type Required Default Description
writer any Yes The writer object returned by initSSEStream().

collection()

Configuration Routing struct mapper

A collection route doesn't require an id because it acts on a collection of objects. photos/search is an example of a collection route, because it acts on (and displays) a collection of objects.

<cfscript>

// 1. Add a search route acting on the photos collection (GET /photos/search)
mapper()
    .resources(name="photos", nested=true)
        .collection()
            .get("search")
        .end()
    .end()
.end();

// 2. Add multiple collection routes (GET /articles/featured, POST /articles/bulk-delete)
mapper()
    .resources(name="articles", nested=true)
        .collection()
            .get("featured")
            .post("bulkDelete")
        .end()
    .end()
.end();

</cfscript>

colorField()

View Helpers Form Object Functions string controller

Builds and returns a string containing a color picker form control based on the supplied objectName and property. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
objectName any Yes The variable name of the object to build the form control for.
property string Yes The name of the property to use in the form control.
association string No The name of the association that the property is located on. Used for building nested forms that work with nested properties. If you are building a form with deep nesting, simply pass in a list to the nested object, and Wheels will figure it out.
position string No The position used when referencing a hasMany relationship in the association argument. Used for building nested forms that work with nested properties. If you are building a form with deep nestings, simply pass in a list of positions, and Wheels will figure it out.
label string No useDefaultLabel The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
errorElement string No span HTML tag to wrap the form control with when the object contains errors.
errorClass string No field-with-errors The class name of the HTML tag that wraps the form control when there are errors.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic color picker bound to a model object property
#colorField(objectName="product", property="themeColor")#

// 2. Color picker with a custom label and a CSS class
#colorField(objectName="user", property="profileColor", label="Profile Color", class="color-picker")#

// 3. Color pickers for nested properties on a hasMany association (e.g., palette swatches)
<cfloop from="1" to="#ArrayLen(design.swatches)#" index="i">
	#colorField(objectName="design", association="swatches", position="#i#", property="hexValue", label="Swatch ##i#")#
</cfloop>

colorFieldTag()

View Helpers Form Tag Functions string controller

Builds and returns a string containing a color picker form control based on the supplied name. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
name string Yes Name to populate in tag's name attribute.
value string No Value to populate in tag's value attribute.
label string No The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic color picker with a default value
#colorFieldTag(name="brandColor", value="##FF5733")#

// 2. Color picker with a label and a CSS class
#colorFieldTag(name="themeColor", value="##336699", label="Theme Color", class="color-input")#

// 3. Color picker with label placement and prepend/append wrappers
#colorFieldTag(name="highlightColor", label="Highlight", labelPlacement="before", prepend="<div class=""field"">", append="</div>")#

column()

Migrator Table Definition Functions any tabledefinition

Adds a column to table definition.

Name Type Required Default Description
columnName string Yes
columnType string Yes
default any No
allowNull boolean No
limit any No
precision numeric No
scale numeric No
// 1. Add a generic string column to a new table
t = createTable(name='articles');
	t.column(columnName='title', columnType='string', limit=255, allowNull=false);
	t.column(columnName='body', columnType='text');
	t.timestamps();
t.create();

// 2. Add a column with a default value and precision/scale (for decimals)
t = createTable(name='products');
	t.column(columnName='name', columnType='string', limit=100, allowNull=false);
	t.column(columnName='price', columnType='decimal', precision=10, scale=2, default='0.00', allowNull=false);
	t.column(columnName='stock', columnType='integer', default='0', allowNull=false);
	t.timestamps();
t.create();

// 3. Add a custom column when altering an existing table
t = changeTable(name='users');
	t.column(columnName='bio', columnType='text', allowNull=true);
t.change();

columnDataForProperty()

Model Class Miscellaneous Functions any model

Returns a struct with data for the named property.

Name Type Required Default Description
property string Yes Name of property to inspect.
// 1. Get all column metadata for a property
data = model("User").columnDataForProperty("email");
// Returns a struct like:
// { column: "email", validationtype: "string", label: "Email" }

// 2. Inspect metadata before using it
data = model("Product").columnDataForProperty("price");
if (isStruct(data)) {
    writeOutput("Column: " & data.column);
    writeOutput("Validation type: " & data.validationtype);
}

// 3. Handle the false return when the property does not exist on the model
data = model("User").columnDataForProperty("nonExistentProp");
if (!isStruct(data)) {
    writeOutput("Property not found on this model.");
}

columnForProperty()

Model Class Miscellaneous Functions any model

Returns the column name mapped for the named model property.

Name Type Required Default Description
property string Yes Name of property to inspect.
// 1. Get the column name mapped to a model property
col = model("User").columnForProperty("firstName");
// col -> "first_name"

// 2. Check the column for a property before building a raw SQL fragment
col = model("Order").columnForProperty("placedAt");
if (col != false) {
    writeOutput("Column in the database: " & col);
}

// 3. Returns false when the property does not exist on the model
col = model("User").columnForProperty("nonExistentProperty");
// col -> false

columnNames()

Model Class Miscellaneous Functions string model

Returns a list of column names in the table mapped to this model. The list is ordered according to the columns' ordinal positions in the database table.

// 1. Get the list of column names for the User model
cols = model("User").columnNames();
// cols -> "id,firstName,lastName,email,createdAt,updatedAt,deletedAt"

// 2. Check whether a specific column exists in the table
if (listFindNoCase(model("User").columnNames(), "email")) {
    writeOutput("The users table has an email column.");
}

// 3. Iterate over every column name
for (col in listToArray(model("User").columnNames())) {
    writeOutput(col);
}

columns()

Model Class Miscellaneous Functions array model

Returns an array of columns names for the table associated with this class. Does not include calculated properties that will be generated by the Wheels ORM.

// 1. Get all column names for the User model
cols = model("User").columns();
// cols -> ["id", "firstName", "lastName", "email", "createdAt", "updatedAt", "deletedAt"]

// 2. Check whether a specific column exists in the table
cols = model("User").columns();
if (arrayFindNoCase(cols, "deletedAt")) {
    writeOutput("Soft-delete column is present");
}

// 3. Iterate over all columns and output their names
cols = model("User").columns();
for (col in cols) {
    writeOutput(col);
}

compareTo()

Model Object Miscellaneous Functions boolean model

Pass in another model object to see if the two objects are the same.

Name Type Required Default Description
object component Yes
// 1. Check if two model objects are the same instance
user1 = model("User").findByKey(1);
user2 = model("User").findByKey(1);
user3 = user1;

isSame = user1.compareTo(user2);
// isSame -> false (two separate fetches produce distinct instances)

isSame = user1.compareTo(user3);
// isSame -> true (user3 is the same object reference as user1)

// 2. Guard against processing the same object twice in a loop
users = model("User").findAll(returnAs="objects");
currentUser = model("User").findByKey(session.userId);

for (u in users) {
    if (!u.compareTo(currentUser)) {
        // process all users except the currently logged-in one
        sendNotification(u);
    }
}

constraints()

Configuration Routing struct mapper

Set variable patterns to use for matching.

<cfscript>

mapper()
    // 1. Constrain a dynamic segment to digits only
    .constraints(id="[0-9]+")
        .resources(name="articles")
    .end()

    // 2. Constrain multiple segments — numeric id and lowercase-only slug
    .constraints(id="[0-9]+", slug="[a-z\-]+")
        .get(name="article", to="articles##show")
        .get(name="articleBySlug", to="articles##showBySlug")
    .end()
.end();

</cfscript>

contentFor()

View Helpers Miscellaneous Functions void controller

Used to store a section's output for rendering within a layout. This content store acts as a stack, so you can store multiple pieces of content for a given section.

Name Type Required Default Description
position any No last The position in the section's stack where you want the content placed. Valid values are first, last, or the numeric position.
overwrite any No false Whether or not to overwrite any of the content. Valid values are false, true, or all.
// 1. Store sidebar content for use in the layout
<cfsavecontent variable="mySidebar">
  <nav>Recent Posts</nav>
</cfsavecontent>
<cfset contentFor(sidebar=mySidebar)>

<!--- In your layout, output the stored section --->
<cfoutput>
  #includeContent("sidebar")#
  #includeContent()#
</cfoutput>

// 2. Push content onto a stack — multiple calls append by default
<cfsavecontent variable="firstScript">
  <script src="/js/base.js"></script>
</cfsavecontent>
<cfset contentFor(scripts=firstScript)>

<cfsavecontent variable="secondScript">
  <script src="/js/page.js"></script>
</cfsavecontent>
<cfset contentFor(scripts=secondScript)>

<!--- Both scripts are rendered in order --->
<cfoutput>#includeContent("scripts")#</cfoutput>

// 3. Prepend content to an existing section using position="first"
<cfsavecontent variable="criticalScript">
  <script src="/js/critical.js"></script>
</cfsavecontent>
<cfset contentFor(position="first", scripts=criticalScript)>

// 4. Overwrite an entire section with overwrite="all"
<cfsavecontent variable="replacementSidebar">
  <nav>Admin Sidebar</nav>
</cfsavecontent>
<cfset contentFor(overwrite="all", sidebar=replacementSidebar)>

// 5. Overwrite a specific position in the stack (position=1, overwrite=true)
<cfsavecontent variable="updatedScript">
  <script src="/js/updated.js"></script>
</cfsavecontent>
<cfset contentFor(position=1, overwrite=true, scripts=updatedScript)>

contentForLayout()

View Helpers Miscellaneous Functions string controller

Includes content for the body section, which equates to the output generated by the view template run by the request.

// 1. Include the view's generated content inside a layout file
// In `app/views/layout.cfm`, place this where the page body should appear
<!DOCTYPE html>
<html>
<head>
    <title>My App</title>
</head>
<body>
    #contentForLayout()#
</body>
</html>

// 2. Combine with includeContent to render named sections alongside the body
// In `app/views/layout.cfm`
<html>
<head>
    #includeContent("head")#
</head>
<body>
    #contentForLayout()#
    #includeContent("footer")#
</body>
</html>

controller()

Configuration Routing struct mapper

Considered deprecated as this doesn't conform to RESTful routing principles; Try not to use this.

Name Type Required Default Description
controller string Yes
name string No [runtime expression]
path string No [runtime expression]

controller()

Global Helpers Miscellaneous Functions any controller model migrator migration tabledefinition

Creates and returns a controller object with your own custom name and params. Used primarily for testing purposes.

Name Type Required Default Description
name string Yes Name of the controller to create.
params struct No [runtime expression] The params struct (combination of form and URL variables).
// 1. Create a controller object for testing (no params)
usersController = controller("users");

// 2. Create a controller object with simulated request params for testing
params = {controller = "users", action = "show", key = 1};
usersController = controller(name = "users", params = params);

// 3. Use with processAction to test an action end-to-end
params = {controller = "users", action = "index"};
usersController = controller(name = "users", params = params);
usersController.processAction();
body = usersController.response();

count()

Model Class Statistics Functions any model

Returns the number of rows that match the arguments (or all rows if no arguments are passed in). Uses the SQL function COUNT. If no records can be found to perform the calculation on, 0 is returned.

Name Type Required Default Description
where string No Maps to the WHERE clause of the query (or HAVING when necessary). The following operators are supported: =, !=, <>, <, <=, >, >=, LIKE, NOT LIKE, IN, NOT IN, IS NULL, IS NOT NULL, AND, and OR (note that the key words need to be written in upper case). You can also use parentheses to group statements. Nested queries not allowed. You do not need to specify the table name(s); Wheels will do that for you.
include string No Associations that should be included in the query using INNER or LEFT OUTER joins (which join type that is used depends on how the association has been set up in your model). If all included associations are set on the current model, you can specify them in a list (e.g. department,addresses,emails). You can build more complex include strings by using parentheses when the association is set on an included model, like album(artist(genre)), for example. These complex include strings only work when returnAs is set to query though.
parameterize any No true Set to true to use cfqueryparam on all columns, or pass in a list of property names to use cfqueryparam on those only.
includeSoftDeletes boolean No false Set to true to include soft-deleted records in the queries that this method runs.
group string No Maps to the GROUP BY clause of the query. You do not need to specify the table name(s); Wheels will do that for you.
// 1. Count all rows in the authors table
authorCount = model("author").count();

// 2. Count authors whose last name starts with "A"
authorOnACount = model("author").count(where="lastName LIKE 'A%'");

// 3. Count authors who have written books with titles starting with "A" (requires a hasMany association from author to book)
authorWithBooksOnACount = model("author").count(include="books", where="books.title LIKE 'A%'");

// 4. Count posts grouped by status, returning a query with one row per status
statusCounts = model("post").count(group="status");
// statusCounts is a query with columns: count, status

// 5. Count the number of comments on a specific post using a dynamic counter method
// (requires a hasMany association from post to comment)
aPost = model("post").findByKey(params.postId);
commentCount = aPost.commentCount();

create()

Migrator Table Definition Functions void tabledefinition

creates the table in the database

create()

Model Class Create Functions any model

Creates a new object, saves it to the database (if the validation permits it), and returns it. If the validation fails, the unsaved object (with errors added to it) is still returned. Property names and values can be passed in either using named arguments or as a struct to the properties argument.

Name Type Required Default Description
properties struct No [runtime expression] The properties you want to set on the object (can also be passed in as named arguments).
parameterize any No true Set to true to use cfqueryparam on all columns, or pass in a list of property names to use cfqueryparam on those only.
reload boolean No false Set to true to force Wheels to query the database even though an identical query for this model may have been run in the same request. (The default in Wheels is to get the second query from the model's request-level cache.)
validate boolean No true Set to false to skip validations for this operation.
transaction string No [runtime expression] Set this to commit to update the database, rollback to run all the database queries but not commit them, or none to skip transaction handling altogether.
callbacks boolean No true Set to false to disable callbacks for this method.
allowExplicitTimestamps boolean No false Set this to true to allow explicit assignment of createdAt or updatedAt properties
// 1. Create a new author and save it to the database
newAuthor = model("author").create(params.author);

// 2. Create using named arguments
newAuthor = model("author").create(firstName="John", lastName="Doe");

// 3. Merge named arguments with a properties struct
newAuthor = model("author").create(active=1, properties=params.author);

// 4. Skip validation when creating (e.g. for seeding trusted data)
newAuthor = model("author").create(properties=params.author, validate=false);

// 5. Create inside a transaction that is rolled back (useful for dry-run testing)
newAuthor = model("author").create(properties=params.author, transaction="rollback");

// 6. Allow explicit createdAt / updatedAt values when importing legacy data
newAuthor = model("author").create(
	firstName="Jane",
	lastName="Smith",
	createdAt="2020-01-15 08:00:00",
	allowExplicitTimestamps=true
);

// 7. Scoped create via a hasOne / hasMany association
// (calls model("order").create(customerId=aCustomer.id, shipping=params.shipping) internally)
aCustomer = model("customer").findByKey(params.customerId);
anOrder = aCustomer.createOrder(shipping=params.shipping);

createMigration()

Migrator General Functions string migrator

Creates a migration file. Whilst you can use this in your application, the recommended usage is via either the CLI or the provided GUI interface

Name Type Required Default Description
migrationName string Yes
templateName string No
migrationPrefix string No timestamp
// 1. Create a blank migration file (uses timestamp prefix by default)
result = application.wheels.migrator.createMigration("CreateUsersTable");
// result -> "The migration 20240815123045_CreateUsersTable.cfc file was created"

// 2. Create a migration from a built-in template (e.g. create-table)
result = application.wheels.migrator.createMigration(
	migrationName="CreatePostsTable",
	templateName="create-table"
);

// 3. Create a migration using a sequential numeric prefix instead of a timestamp
result = application.wheels.migrator.createMigration(
	migrationName="AddIndexToUsers",
	migrationPrefix="numeric"
);
// result -> "The migration 001_AddIndexToUsers.cfc file was created"

createTable()

Migrator Migration Functions TableDefinition migration

Creates a table definition object to store table properties Only available in a migration CFC

Name Type Required Default Description
name string Yes The name of the table to create
force boolean No false whether to drop the table before creating it
id boolean No true Whether to create a default primarykey or not
primaryKey string No id Name of the primary key field to create
// 1. Create a users table with standard columns and timestamps
t = createTable(name="users");
	t.string(columnNames="firstName,lastName", default="", allowNull=false, limit=50);
	t.string(columnNames="email", default="", allowNull=false, limit=255);
	t.string(columnNames="passwordHash", default="", allowNull=true, limit=500);
	t.boolean(columnNames="verified", default=false);
	t.integer(columnNames="roleId", default=0, allowNull=false);
	t.timestamps();
t.create();

// 2. Create a table with a custom string primary key (disabling the auto integer id)
t = createTable(name="tokens", id=false);
	t.primaryKey(name="id", allowNull=false, type="string", limit=36);
	t.string(columnNames="userId", allowNull=false, limit=36);
	t.datetime(columnNames="expiresAt", allowNull=false);
	t.timestamps();
t.create();

// 3. Create a join table with composite primary keys and force=true to recreate if it already exists
t = createTable(name="userRoles", id=false, force=true);
	t.primaryKey(name="userId", allowNull=false, limit=11);
	t.primaryKey(name="roleId", allowNull=false, limit=11);
t.create();

createView()

Migrator Migration Functions ViewDefinition migration

Creates a view definition object to store view properties Only available in a migration CFC

Name Type Required Default Description
name string Yes Name of the view to change properties on
// 1. Create a simple database view that joins users and roles
v = createView(name="userRoles");
v.selectStatement(sql="SELECT u.id, u.firstName, u.lastName, r.name AS roleName FROM users u INNER JOIN roles r ON u.roleId = r.id");
v.create();

// 2. Create a view for active (non-deleted) users using method chaining
createView(name="activeUsers")
    .selectStatement(sql="SELECT id, firstName, lastName, email FROM users WHERE deletedAt IS NULL")
    .create();

// 3. Full up/down migration using createView and dropView
component extends="wheels.migrator.Migration" {
    function up() {
        createView(name="publishedArticles")
            .selectStatement(sql="SELECT id, title, body, authorId, publishedAt FROM articles WHERE publishedAt IS NOT NULL")
            .create();
    }
    function down() {
        dropView(name="publishedArticles");
    }
}

csrfMetaTags()

View Helpers Miscellaneous Functions string controller

Include this in your layouts' head sections to include meta tags containing the authenticity token for use by JavaScript AJAX requests needing to POST data to your application.

// 1. Include CSRF meta tags in your layout's <head> section
//    so that JavaScript AJAX requests can read the token and send it
//    as a request header when POSTing data to your application.
<head>
  <title>My App</title>
  #csrfMetaTags()#
</head>

// 2. Reading the token in JavaScript (e.g. with fetch) using the meta tags above
//    The rendered HTML will contain two meta tags like:
//    <meta name="csrf-param" content="authenticityToken">
//    <meta name="csrf-token" content="<generated-token>">
//
//    In your JavaScript you can then do:
//    const token = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
//    fetch('/posts', { method: 'POST', headers: { 'authenticityToken': token }, body: ... });

cycle()

View Helpers Miscellaneous Functions string controller

Cycles through list values every time it is called.

Name Type Required Default Description
values string Yes List of values to cycle through.
name string No default Name to give the cycle. Useful when you use multiple cycles on a page.
// 1. Alternate CSS classes on table rows
// Outputs "odd" on the first row, "even" on the second, "odd" on the third, etc.
<table>
	<thead>
		<tr>
			<th>Name</th>
			<th>Phone</th>
		</tr>
	</thead>
	<tbody>
		<cfoutput query="employees">
			<tr class="#cycle("odd,even")#">
				<td>#employees.name#</td>
				<td>#employees.phone#</td>
			</tr>
		</cfoutput>
	</tbody>
</table>

// 2. Use named cycles when running multiple cycles simultaneously
// Cycle "row" and "highlight" advance independently
<cfoutput query="employees">
	<cfset rowClass = cycle(values="even,odd", name="row")>
	<cfset hlClass = cycle(values="highlight,normal,normal", name="highlight")>
	<tr class="#rowClass# #hlClass#">
		<td>#employees.name#</td>
	</tr>
</cfoutput>

// 3. Reset a cycle so it starts over from the first value
<cfoutput query="departments" group="departmentId">
	<div class="#cycle(values="even,odd", name="row")#">
		<ul>
			<cfoutput>
				<cfset rank = cycle(values="president,vice-president,director,manager,specialist,intern", name="position")>
				<li class="#rank#">#employees.name#</li>
			</cfoutput>
		</ul>
	</div>
	<cfset resetCycle("position")>
</cfoutput>

dataSource()

Model Configuration Miscellaneous Functions void model

Use this method to override the data source connection information for this model.

Name Type Required Default Description
datasource string Yes The data source name to connect to.
username string No The username for the data source.
password string No The password for the data source.
// 1. Override the data source for a model (basic usage).
// In models/User.cfc
config() {
	// Tell Wheels to use the data source named `users_source` instead of
	// the default one whenever this model makes SQL calls.
	dataSource("users_source");
}

// 2. Override the data source with explicit credentials.
// In models/LegacyOrder.cfc
config() {
	dataSource(datasource="legacy_db", username="app_reader", password="s3cr3t");
}

date()

Migrator Table Definition Functions any tabledefinition

Adds date columns to table definition.

Name Type Required Default Description
columnNames string No
default any No
allowNull boolean No
// 1. Add a single date column to a new table
t = createTable(name='events');
	t.string(columnNames='title', limit=255, allowNull=false);
	t.date(columnNames='eventDate', allowNull=false);
	t.timestamps();
t.create();

// 2. Add multiple date columns at once
t = createTable(name='subscriptions');
	t.string(columnNames='plan', limit=100, allowNull=false);
	t.date(columnNames='startDate,endDate', allowNull=false);
	t.timestamps();
t.create();

// 3. Add a date column with a default value to an existing table
t = changeTable(name='users');
	t.date(columnNames='birthDate', allowNull=true);
t.change();

dateField()

View Helpers Form Object Functions string controller

Builds and returns a string containing a date field form control based on the supplied objectName and property. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
objectName any Yes The variable name of the object to build the form control for.
property string Yes The name of the property to use in the form control.
association string No The name of the association that the property is located on. Used for building nested forms that work with nested properties. If you are building a form with deep nesting, simply pass in a list to the nested object, and Wheels will figure it out.
position string No The position used when referencing a hasMany relationship in the association argument. Used for building nested forms that work with nested properties. If you are building a form with deep nestings, simply pass in a list of positions, and Wheels will figure it out.
min string No Minimum allowed date (YYYY-MM-DD format).
max string No Maximum allowed date (YYYY-MM-DD format).
step string No
label string No useDefaultLabel The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
errorElement string No span HTML tag to wrap the form control with when the object contains errors.
errorClass string No field-with-errors The class name of the HTML tag that wraps the form control when there are errors.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic date field bound to a model object property
#dateField(objectName="event", property="startDate")#

// 2. Date field with a custom label, min/max constraints, and a CSS class
#dateField(objectName="event", property="startDate", label="Start Date", min="2024-01-01", max="2024-12-31", class="date-picker")#

// 3. Date fields for nested properties on a hasMany association (e.g., schedule items)
<cfloop from="1" to="#ArrayLen(project.milestones)#" index="i">
	#dateField(objectName="project", association="milestones", position="#i#", property="dueDate", label="Due Date ##i#")#
</cfloop>

dateFieldTag()

View Helpers Form Tag Functions string controller

Builds and returns a string containing a date field form control based on the supplied name. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
name string Yes Name to populate in tag's name attribute.
value string No Value to populate in tag's value attribute.
min string No Minimum allowed date (YYYY-MM-DD format).
max string No Maximum allowed date (YYYY-MM-DD format).
step string No
label string No The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic date field with a name and label
#dateFieldTag(name="startDate", label="Start Date")#

// 2. Pre-filled date value with min/max constraints
#dateFieldTag(name="eventDate", value="2024-06-15", min="2024-01-01", max="2024-12-31", label="Event Date")#

// 3. Date field with extra HTML attributes passed through
#dateFieldTag(name="dueDate", label="Due Date", class="form-control", id="due-date-input")#

dateSelect()

View Helpers Form Object Functions string controller

Builds and returns a string containing three select form controls for month, day, and year based on the supplied objectName and property.

Name Type Required Default Description
objectName any No The variable name of the object to build the form control for.
property string No The name of the property to use in the form control.
association string No The name of the association that the property is located on. Used for building nested forms that work with nested properties. If you are building a form with deep nesting, simply pass in a list to the nested object, and Wheels will figure it out.
position string No The position used when referencing a hasMany relationship in the association argument. Used for building nested forms that work with nested properties. If you are building a form with deep nestings, simply pass in a list of positions, and Wheels will figure it out.
order string No month,day,year Use to change the order of or exclude date select tags.
separator string No Use to change the character that is displayed between the date select tags.
startYear numeric No 2021 First year in select list.
endYear numeric No 2031 Last year in select list.
monthDisplay string No names Pass in names, numbers, or abbreviations to control display.
monthNames string No January,February,March,April,May,June,July,August,September,October,November,December
monthAbbreviations string No Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec
includeBlank any No false Whether to include a blank option in the select form control. Pass true to include a blank line or a string that should represent what display text should appear for the empty value (for example, "- Select One -").
label string No false The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
errorElement string No span HTML tag to wrap the form control with when the object contains errors.
errorClass string No field-with-errors The class name of the HTML tag that wraps the form control when there are errors.
combine boolean No Set to false to not combine the select parts into a single DateTime object.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
<!--- Basic date select bound to a model object --->
#dateSelect(objectName="user", property="dateOfBirth")#

<!--- Show fields to select only month and year --->
#dateSelect(objectName="order", property="expirationDate", order="month,year")#

<!--- Display month as numbers and include a blank option --->
#dateSelect(objectName="event", property="startDate", monthDisplay="numbers", includeBlank=true)#

<!--- Restrict year range and use abbreviated month names --->
#dateSelect(objectName="reservation", property="checkInDate", startYear=2024, endYear=2030, monthDisplay="abbreviations")#

dateSelectTags()

View Helpers Form Tag Functions string controller

Builds and returns a string containing three select form controls (month, day, and year) based on a name and value.

Name Type Required Default Description
name string Yes Name to populate in tag's name attribute.
selected string No Value of option that should be selected by default.
order string No month,day,year Use to change the order of or exclude date select tags.
separator string No Use to change the character that is displayed between the date select tags.
startYear numeric No 2021 First year in select list.
endYear numeric No 2031 Last year in select list.
monthDisplay string No names Pass in names, numbers, or abbreviations to control display.
monthNames string No January,February,March,April,May,June,July,August,September,October,November,December [see:dateSelect].
monthAbbreviations string No Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec [see:dateSelect].
includeBlank any No false Whether to include a blank option in the select form control. Pass true to include a blank line or a string that should represent what display text should appear for the empty value (for example, "- Select One -").
label string No The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
combine boolean No Set to false to not combine the select parts into a single DateTime object.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic date selection - the "Tag" version accepts `name` and `selected` directly instead of binding to a model object
#dateSelectTags(name="dateStart", selected=params.dateStart)#

// 2. Show only month and year fields (omit day)
#dateSelectTags(name="expiration", selected=params.expiration, order="month,year")#

// 3. Custom year range with a blank option and a label
#dateSelectTags(name="birthdate", selected=params.birthdate, startYear=1920, endYear=2024, includeBlank=true, label="Date of Birth")#

datetime()

Migrator Table Definition Functions any tabledefinition

adds datetime columns to table definition

Name Type Required Default Description
columnNames string No
default any No
allowNull boolean No
// 1. Add a single datetime column to a new table
t = createTable(name='orders');
	t.string(columnNames='status', limit=50, allowNull=false);
	t.datetime(columnNames='placedAt', allowNull=false);
	t.timestamps();
t.create();

// 2. Add multiple datetime columns at once
t = createTable(name='appointments');
	t.string(columnNames='title', limit=255, allowNull=false);
	t.datetime(columnNames='startAt,endAt', allowNull=false);
	t.timestamps();
t.create();

// 3. Add a nullable datetime column with a default to an existing table
t = changeTable(name='posts');
	t.datetime(columnNames='publishedAt', allowNull=true, default='NOW()');
t.change();

dateTimeSelect()

View Helpers Form Object Functions string controller

Builds and returns a string containing six select form controls (three for date selection and the remaining three for time selection) based on the supplied objectName and property.

Name Type Required Default Description
objectName string Yes The variable name of the object to build the form control for.
property string Yes The name of the property to use in the form control.
association string No The name of the association that the property is located on. Used for building nested forms that work with nested properties. If you are building a form with deep nesting, simply pass in a list to the nested object, and Wheels will figure it out.
position string No The position used when referencing a hasMany relationship in the association argument. Used for building nested forms that work with nested properties. If you are building a form with deep nestings, simply pass in a list of positions, and Wheels will figure it out.
dateOrder string No month,day,year Use to change the order of or exclude date select tags.
dateSeparator string No Use to change the character that is displayed between the date select tags.
startYear numeric No 2021 First year in select list.
endYear numeric No 2031 Last year in select list.
monthDisplay string No names Pass in names, numbers, or abbreviations to control display.
monthNames string No January,February,March,April,May,June,July,August,September,October,November,December
monthAbbreviations string No Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec
timeOrder string No hour,minute,second Use to change the order of or exclude time select tags.
timeSeparator string No : Use to change the character that is displayed between the time select tags.
minuteStep numeric No 1 Pass in 10 to only show minute 10, 20, 30, etc.
secondStep numeric No 1 Pass in 10 to only show seconds 10, 20, 30, etc
separator string No - Use to change the character that is displayed between the first and second set of select tags.
includeBlank any No false Whether to include a blank option in the select form control. Pass true to include a blank line or a string that should represent what display text should appear for the empty value (for example, "- Select One -").
label string No false The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
errorElement string No span HTML tag to wrap the form control with when the object contains errors.
errorClass string No field-with-errors The class name of the HTML tag that wraps the form control when there are errors.
combine boolean No Set to false to not combine the select parts into a single DateTime object.
twelveHour boolean No false Whether to display the hours in 24 or 12 hour format. 12 hour format has AM/PM drop downs
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic date and time select for an article's published date
#dateTimeSelect(objectName="article", property="publishedAt")#

// 2. Show only month, day, hour, and minute (exclude year and second)
#dateTimeSelect(objectName="appointment", property="dateTimeStart", dateOrder="month,day", timeOrder="hour,minute")#

// 3. Use 12-hour time format with a blank option and a custom year range
#dateTimeSelect(objectName="event", property="startsAt", twelveHour=true, includeBlank=true, startYear=2020, endYear=2030)#

// 4. Display month as numbers, step minutes by 15, and add a label
#dateTimeSelect(objectName="meeting", property="scheduledAt", monthDisplay="numbers", minuteStep=15, label="Scheduled Date & Time")#

dateTimeSelectTags()

View Helpers Form Tag Functions string controller

Builds and returns a string containing six select form controls (three for date selection and the remaining three for time selection) based on a name.

Name Type Required Default Description
name string Yes Name to populate in tag's name attribute.
selected string No Value of option that should be selected by default.
dateOrder string No month,day,year Use to change the order of or exclude date select tags.
dateSeparator string No Use to change the character that is displayed between the date select tags.
startYear numeric No 2021 First year in select list.
endYear numeric No 2031 Last year in select list.
monthDisplay string No names Pass in names, numbers, or abbreviations to control display.
monthNames string No January,February,March,April,May,June,July,August,September,October,November,December [see:dateSelect].
monthAbbreviations string No Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec [see:dateSelect].
timeOrder string No hour,minute,second Use to change the order of or exclude time select tags.
timeSeparator string No : Use to change the character that is displayed between the time select tags.
minuteStep numeric No 1 Pass in 10 to only show minute 10, 20, 30, etc.
secondStep numeric No 1 Pass in 10 to only show seconds 10, 20, 30, etc.
separator string No - Use to change the character that is displayed between the first and second set of select tags.
includeBlank any No false Whether to include a blank option in the select form control. Pass true to include a blank line or a string that should represent what display text should appear for the empty value (for example, "- Select One -").
label string No The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
combine boolean No Set to false to not combine the select parts into a single DateTime object.
twelveHour boolean No false whether to display the hours in 24 or 12 hour format. 12 hour format has AM/PM drop downs
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic usage - the "Tag" version accepts `name` and `selected` directly instead of binding to a model object
#dateTimeSelectTags(name="dateTimeStart", selected=params.dateTimeStart)#

// 2. Show only month/day for the date portion and hour/minute for the time portion
#dateTimeSelectTags(name="dateTimeStart", selected=params.dateTimeStart, dateOrder="month,day", timeOrder="hour,minute")#

// 3. Custom year range, 15-minute steps, 12-hour format, and a label
#dateTimeSelectTags(name="scheduledAt", selected=params.scheduledAt, startYear=2020, endYear=2030, minuteStep=15, twelveHour=true, label="Scheduled Date & Time")#

daySelectTag()

View Helpers Form Tag Functions string controller

Builds and returns a string containing a select form control for the days of the month based on the supplied name.

Name Type Required Default Description
name string Yes Name to populate in tag's name attribute.
selected string No The day that should be selected initially.
includeBlank any No false Whether to include a blank option in the select form control. Pass true to include a blank line or a string that should represent what display text should appear for the empty value (for example, "- Select One -").
label string No The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic usage: render a day-of-month select for a standalone form (not bound to a model)
#daySelectTag(name="day", selected=params.day)#

// 2. Pre-select day 15 and include a blank prompt at the top
#daySelectTag(name="birthDay", selected=15, includeBlank="-- Select Day --")#

// 3. Wrap the control with a label and surrounding HTML via prepend/append
#daySelectTag(name="day", selected=params.day, label="Day", prepend="<div class=""field"">", append="</div>")#

decimal()

Migrator Table Definition Functions any tabledefinition

adds decimal columns to table definition

Name Type Required Default Description
columnNames string No
default any No
allowNull boolean No
precision numeric No
scale numeric No
// 1. Add a single decimal column to a new table
t = createTable(name='products');
	t.string(columnNames='name', limit=255, allowNull=false);
	t.decimal(columnNames='price', precision=10, scale=2, allowNull=false);
	t.timestamps();
t.create();

// 2. Add multiple decimal columns at once
t = createTable(name='measurements');
	t.string(columnNames='label', limit=100, allowNull=false);
	t.decimal(columnNames='length,width,height', precision=8, scale=4, allowNull=false);
	t.timestamps();
t.create();

// 3. Add a nullable decimal column with a default to an existing table
t = changeTable(name='orders');
	t.decimal(columnNames='discount', precision=5, scale=2, allowNull=true, default='0.00');
t.change();

delete()

Configuration Routing struct mapper

Create a route that matches a URL requiring an HTTP DELETE method. We recommend using this matcher to expose actions that delete database records.

Name Type Required Default Description
name string No Camel-case name of route to reference when build links and form actions (e.g., blogPost).
pattern string No Overrides the URL pattern that will match the route. The default value is a dasherized version of name (e.g., a name of blogPost generates a pattern of blog-post).
to string No Set controller##action combination to map the route to. You may use either this argument or a combination of controller and action.
controller string No Map the route to a given controller. This must be passed along with the action argument.
action string No Map the route to a given action within the controller. This must be passed along with the controller argument.
package string No Indicates a subfolder that the controller will be referenced from (but not added to the URL pattern). For example, if you set this to admin, the controller will be located at admin/YourController.cfc, but the URL path will not contain admin/.
on string No If this route is within a nested resource, you can set this argument to member or collection. A member route contains a reference to the resource's key, while a collection route does not.
redirect string No Redirect via 302 to this URL when this route is matched. Has precedence over controller/action. Use either an absolute link like /about/, or a full canonical link.
<cfscript>

mapper()
    // Route name:  articleReview
    // Example URL: /articles/987/reviews/12542
    // Controller:  Reviews
    // Action:      delete
    .delete(name="articleReview", pattern="articles/[articleKey]/reviews/[key]", to="reviews##delete")

    // Route name:  cookedBooks
    // Example URL: /cooked-books
    // Controller:  CookedBooks
    // Action:      delete
    .delete(name="cookedBooks", controller="cookedBooks", action="delete")

    // Route name:  logout
    // Example URL: /logout
    // Controller:  Sessions
    // Action:      delete
    .delete(name="logout", to="sessions##delete")

    // Route name:  clientsStatus
    // Example URL: /statuses/4918
    // Controller:  clients.Statuses
    // Action:      delete
    .delete(name="statuses", to="statuses##delete", package="clients")

    // Route name:  blogComment
    // Example URL: /comments/5432
    // Controller:  blog.Comments
    // Action:      delete
    .delete(
        name="comment",
        pattern="comments/[key]",
        to="comments##delete",
        package="blog"
    )
.end();

</cfscript>

delete()

Model Object CRUD Functions boolean model

Deletes the object, which means the row is deleted from the database (unless prevented by a beforeDelete callback). Returns true on successful deletion of the row, false otherwise.

Name Type Required Default Description
parameterize any No true Set to true to use cfqueryparam on all columns, or pass in a list of property names to use cfqueryparam on those only.
transaction string No [runtime expression] Set this to commit to update the database, rollback to run all the database queries but not commit them, or none to skip transaction handling altogether.
callbacks boolean No true Set to false to disable callbacks for this method.
includeSoftDeletes boolean No false Set to true to include soft-deleted records in the queries that this method runs.
softDelete boolean No true Set to false to permanently delete a record, even if it has a soft delete column.
// 1. Get a post object and then delete it from the database.
post = model("Post").findByKey(33);
post.delete();

// 2. Permanently delete a record even if the model uses soft deletes.
user = model("User").findByKey(params.userId);
user.delete(softDelete=false);

// 3. Delete a record without running callbacks (e.g. skip `beforeDelete` / `afterDelete`).
comment = model("Comment").findByKey(params.commentId);
comment.delete(callbacks=false);

// 4. If you have a `hasMany` association setup from `post` to `comment`, you can do a scoped call. (The `deleteComment` method below will call `comment.delete()` internally.)
post = model("Post").findByKey(params.postId);
comment = model("Comment").findByKey(params.commentId);
post.deleteComment(comment);

deleteAll()

Model Class Delete Functions numeric model

Deletes all records that match the where argument. By default, objects will not be instantiated and therefore callbacks and validations are not invoked. You can change this behavior by passing in instantiate=true. Returns the number of records that were deleted.

Name Type Required Default Description
where string No Maps to the WHERE clause of the query (or HAVING when necessary). The following operators are supported: =, !=, <>, <, <=, >, >=, LIKE, NOT LIKE, IN, NOT IN, IS NULL, IS NOT NULL, AND, and OR (note that the key words need to be written in upper case). You can also use parentheses to group statements. Nested queries not allowed. You do not need to specify the table name(s); Wheels will do that for you.
include string No Associations that should be included in the query using INNER or LEFT OUTER joins (which join type that is used depends on how the association has been set up in your model). If all included associations are set on the current model, you can specify them in a list (e.g. department,addresses,emails). You can build more complex include strings by using parentheses when the association is set on an included model, like album(artist(genre)), for example. These complex include strings only work when returnAs is set to query though.
reload boolean No false Set to true to force Wheels to query the database even though an identical query for this model may have been run in the same request. (The default in Wheels is to get the second query from the model's request-level cache.)
parameterize any No true Set to true to use cfqueryparam on all columns, or pass in a list of property names to use cfqueryparam on those only.
instantiate boolean No false Whether or not to instantiate the object(s) first. When objects are not instantiated, any callbacks and validations set on them will be skipped.
useIndex struct No [runtime expression] If you want to specify table index hints, pass in a structure of index names using your model names as the structure keys. Eg: {user="idx_users", post="idx_posts"}. This feature is only supported by MySQL and SQL Server.
transaction string No [runtime expression] Set this to commit to update the database, rollback to run all the database queries but not commit them, or none to skip transaction handling altogether.
callbacks boolean No true Set to false to disable callbacks for this method.
includeSoftDeletes boolean No false Set to true to include soft-deleted records in the queries that this method runs.
softDelete boolean No true Set to false to permanently delete a record, even if it has a soft delete column.
// 1. Delete all inactive users without instantiating them (skips callbacks and validations).
recordsDeleted = model("User").deleteAll(where="inactive=1");

// 2. Delete all inactive users and run their beforeDelete / afterDelete callbacks.
recordsDeleted = model("User").deleteAll(where="inactive=1", instantiate=true);

// 3. Permanently delete soft-deleted records (bypass the soft-delete column).
recordsDeleted = model("User").deleteAll(where="inactive=1", softDelete=false);

// 4. If you have a `hasMany` association from `Post` to `Comment`, you can use a scoped call. (The `deleteAllComments` method below calls `model("Comment").deleteAll(where="postId=#post.id#")` internally.)
post = model("Post").findByKey(params.postId);
howManyDeleted = post.deleteAllComments();

deleteByKey()

Model Class Delete Functions boolean model

Finds the record with the supplied key and deletes it. Returns true on successful deletion of the row, false otherwise.

Name Type Required Default Description
key any Yes Primary key value(s) of the record to fetch. Separate with comma if passing in multiple primary key values. Accepts a string, list, or a numeric value.
reload boolean No false Set to true to force Wheels to query the database even though an identical query for this model may have been run in the same request. (The default in Wheels is to get the second query from the model's request-level cache.)
transaction string No [runtime expression] Set this to commit to update the database, rollback to run all the database queries but not commit them, or none to skip transaction handling altogether.
callbacks boolean No true Set to false to disable callbacks for this method.
includeSoftDeletes boolean No false Set to true to include soft-deleted records in the queries that this method runs.
softDelete boolean No true Set to false to permanently delete a record, even if it has a soft delete column.
// 1. Delete the user with the primary key value of 1.
result = model("User").deleteByKey(1);
// result -> true (if the row was deleted), false otherwise

// 2. Permanently delete a soft-deletable record (bypass soft delete).
result = model("User").deleteByKey(key=1, softDelete=false);

// 3. Delete using a composite primary key (comma-separated values).
result = model("OrderItem").deleteByKey("42,7");

// 4. Delete within a transaction that can be rolled back (useful for testing).
result = model("User").deleteByKey(key=1, transaction="rollback");

deleteOne()

Model Class Delete Functions boolean model

Gets an object based on conditions and deletes it.

Name Type Required Default Description
where string No Maps to the WHERE clause of the query (or HAVING when necessary). The following operators are supported: =, !=, <>, <, <=, >, >=, LIKE, NOT LIKE, IN, NOT IN, IS NULL, IS NOT NULL, AND, and OR (note that the key words need to be written in upper case). You can also use parentheses to group statements. Nested queries not allowed. You do not need to specify the table name(s); Wheels will do that for you.
order string No Maps to the ORDER BY clause of the query. You do not need to specify the table name(s); Wheels will do that for you.
reload boolean No false Set to true to force Wheels to query the database even though an identical query for this model may have been run in the same request. (The default in Wheels is to get the second query from the model's request-level cache.)
transaction string No [runtime expression] Set this to commit to update the database, rollback to run all the database queries but not commit them, or none to skip transaction handling altogether.
callbacks boolean No true Set to false to disable callbacks for this method.
includeSoftDeletes boolean No false Set to true to include soft-deleted records in the queries that this method runs.
useIndex struct No [runtime expression] If you want to specify table index hints, pass in a structure of index names using your model names as the structure keys. Eg: {user="idx_users", post="idx_posts"}. This feature is only supported by MySQL and SQL Server.
softDelete boolean No true Set to false to permanently delete a record, even if it has a soft delete column.
// 1. Delete the user who signed up most recently.
result = model("User").deleteOne(order="signupDate DESC");

// 2. Delete the oldest unpaid invoice for a given customer.
result = model("Invoice").deleteOne(
	where="customerId=#params.customerId# AND status='unpaid'",
	order="createdAt ASC"
);

// 3. Permanently delete a soft-deletable record (bypass soft-delete behaviour).
result = model("User").deleteOne(
	where="status='banned'",
	order="createdAt ASC",
	softDelete=false
);

// 4. If you have a `hasOne` association set up from `User` to `Profile` you can do a scoped call.
// The `deleteProfile` method will call `model("Profile").deleteOne(where="userId=#aUser.id#")` internally.
aUser = model("User").findByKey(params.userId);
aUser.deleteProfile();

deobfuscateParam()

Global Helpers Miscellaneous Functions string controller model mapper migrator migration tabledefinition

Deobfuscates a value.

Name Type Required Default Description
param string Yes The value to deobfuscate.
// 1. Deobfuscate a URL parameter to get the original numeric ID
// (Wheels automatically obfuscates numeric URL params when obfuscateUrls is enabled)
originalId = deobfuscateParam("b7ab9a50");
// originalId -> "35"

// 2. Round-trip: obfuscate a value, then deobfuscate it back
obfuscated = obfuscateParam("100");
original = deobfuscateParam(obfuscated);
// original -> "100"

// 3. Non-obfuscated values (e.g. already plain integers) are returned as-is
passthrough = deobfuscateParam("42");
// passthrough -> "42"

distanceOfTimeInWords()

Global Helpers Date Functions string controller model mapper migrator migration tabledefinition

Pass in two dates to this method, and it will return a string describing the difference between them.

Name Type Required Default Description
fromTime date Yes Date to compare from.
toTime date Yes Date to compare to.
includeSeconds boolean No false Whether or not to include the number of seconds in the returned string.
// 1. Compare two dates about a month apart
rightNow = Now();
aWhileAgo = DateAdd("d", -30, rightNow);
writeOutput(distanceOfTimeInWords(aWhileAgo, rightNow));
// -> "about 1 month"

// 2. Show a short gap with seconds included
justNow = Now();
fiveSecondsAgo = DateAdd("s", -5, justNow);
writeOutput(distanceOfTimeInWords(fiveSecondsAgo, justNow, includeSeconds=true));
// -> "less than 5 seconds"

// 3. Show various time ranges
now = Now();
writeOutput(distanceOfTimeInWords(DateAdd("n", -2, now), now));
// -> "2 minutes"

writeOutput(distanceOfTimeInWords(DateAdd("h", -3, now), now));
// -> "about 3 hours"

writeOutput(distanceOfTimeInWords(DateAdd("d", -5, now), now));
// -> "5 days"

writeOutput(distanceOfTimeInWords(DateAdd("yyyy", -2, now), now));
// -> "over 2 years"

doctor()

Migrator General Functions struct migrator

Returns a comprehensive health report on the migrator state. Pure read — no mutation. Used by wheels migrate doctor to surface orphans, gaps, and pending migrations in one pass. Result struct: - healthy: boolean — true iff no orphans AND no pending - currentVersion: string — highest applied version (may be orphan) - orphans: array — DB versions with no matching file - pending: array — local files not yet applied - summary: struct with .total, .applied, .pending, .orphan counts - message: human-readable one-paragraph summary See issue #2780 / PR #2798 for the orphan detection foundation.

down()

Migrator Migration Functions void migration

Migrates down: will be executed when migrating your schema backward Along with up(), these are the two main functions in any migration file Only available in a migration CFC

// 1. Reverse a table creation by dropping the table
// Called automatically when rolling back this migration
function down() {
	var state = {};
	transaction {
		try {
			dropTable("employees");
		} catch (any e) {
			state.exception = e;
		}

		if (structKeyExists(state, "exception")) {
			transaction action="rollback";
			throw(
				errorCode = "1",
				detail    = state.exception.detail,
				message   = state.exception.message,
				type      = "any"
			);
		} else {
			transaction action="commit";
		}
	}
}

// 2. Reverse an addColumn() call by removing the column
function down() {
	var state = {};
	transaction {
		try {
			removeColumn(table="users", columnName="biography");
		} catch (any e) {
			state.exception = e;
		}

		if (structKeyExists(state, "exception")) {
			transaction action="rollback";
			throw(
				errorCode = "1",
				detail    = state.exception.detail,
				message   = state.exception.message,
				type      = "any"
			);
		} else {
			transaction action="commit";
		}
	}
}

// 3. Paired up() and down() inside a full migration component
component extends="[extends]" hint="Add status column to orders" {

	function up() {
		var state = {};
		transaction {
			try {
				addColumn(table="orders", columnType="string", columnName="status", limit=50, default="pending");
			} catch (any e) {
				state.exception = e;
			}

			if (structKeyExists(state, "exception")) {
				transaction action="rollback";
				throw(
					errorCode = "1",
					detail    = state.exception.detail,
					message   = state.exception.message,
					type      = "any"
				);
			} else {
				transaction action="commit";
			}
		}
	}

	function down() {
		var state = {};
		transaction {
			try {
				removeColumn(table="orders", columnName="status");
			} catch (any e) {
				state.exception = e;
			}

			if (structKeyExists(state, "exception")) {
				transaction action="rollback";
				throw(
					errorCode = "1",
					detail    = state.exception.detail,
					message   = state.exception.message,
					type      = "any"
				);
			} else {
				transaction action="commit";
			}
		}
	}

}

dropForeignKey()

Migrator Migration Functions void migration

Drops a foreign key constraint from the database Only available in a migration CFC

Name Type Required Default Description
table string Yes The table name to perform the operation on
keyName string Yes the name of the key to drop
// 1. Drop a foreign key constraint by its explicit name
// In the down() function, remove a foreign key added in up()
dropForeignKey(table="orders", keyName="FK_orders_customers");

// 2. Drop a foreign key that was created via addReference()
// addReference() creates keys named FK_<table>_<pluralizedReference>
// So addReference(table="comments", referenceName="post") creates "FK_comments_posts"
dropForeignKey(table="comments", keyName="FK_comments_posts");

// 3. Use inside a migration's down() to reverse an addForeignKey() call
// up() called: addForeignKey(table="profiles", referenceTable="users", column="userId", referenceColumn="id")
// down() reverses it:
dropForeignKey(table="profiles", keyName="FK_profiles_users");

dropReference()

Migrator Migration Functions void migration

Drop a foreign key constraint from the database, using the reference name that was used to create it Only available in a migration CFC

Name Type Required Default Description
table string Yes The table name to perform the operation on
referenceName string No the name of the reference to drop
columnName string No Alias for referenceName (consistent with the modern migrator surface — columnName / columnNames are accepted alongside the legacy form).
columnNames string No Plural alias for referenceName. When both columnName and columnNames are supplied, columnNames wins.
// 1. Drop the foreign key from comments.postId back to posts.id
// Removes the constraint named FK_comments_posts
dropReference(table="comments", referenceName="post");

// 2. Drop a foreign key from order_items back to orders
// Removes the constraint named FK_order_items_orders
dropReference(table="order_items", referenceName="order");

// 3. Use dropReference in the down() of a migration that added a reference in up()
// In your migration CFC:
//
// public void function up() {
//     addReference(table="comments", referenceName="post");
// }
//
// public void function down() {
//     dropReference(table="comments", referenceName="post");
// }

dropTable()

Migrator Migration Functions void migration

Drops a table from the database Only available in a migration CFC

Name Type Required Default Description
name string Yes Name of the table to drop
// 1. Drop a table in the down() migration (reversing a createTable in up())
component extends="wheels.migrator.Migration" hint="Add products table" {

	function up() {
		t = createTable(name="products");
		t.string(columnNames="name", allowNull=false);
		t.decimal(columnNames="price", precision=10, scale=2);
		t.boolean(columnNames="active", default=1);
		t.timestamps();
		t.create();
	}

	function down() {
		dropTable("products");
	}

}

// 2. Drop multiple tables in a single down() migration
component extends="wheels.migrator.Migration" hint="Add orders and line items tables" {

	function up() {
		t = createTable(name="lineItems");
		t.integer(columnNames="orderId");
		t.integer(columnNames="productId");
		t.integer(columnNames="quantity");
		t.timestamps();
		t.create();

		t = createTable(name="orders");
		t.integer(columnNames="userId");
		t.string(columnNames="status");
		t.timestamps();
		t.create();
	}

	function down() {
		dropTable("lineItems");
		dropTable("orders");
	}

}

dropView()

Migrator Migration Functions void migration

drops a view from the database Only available in a migration CFC

Name Type Required Default Description
name string Yes Name of the view to drop
// 1. Drop a view in the down() migration (reversing a createView in up())
component extends="wheels.migrator.Migration" hint="Add active users view" {

	function up() {
		createView(name="activeUsers")
			.selectStatement(sql="SELECT id, firstName, lastName, email FROM users WHERE deletedAt IS NULL")
			.create();
	}

	function down() {
		dropView(name="activeUsers");
	}

}

// 2. Drop multiple views in a single down() migration
component extends="wheels.migrator.Migration" hint="Add reporting views" {

	function up() {
		createView(name="publishedArticles")
			.selectStatement(sql="SELECT id, title, authorId, publishedAt FROM articles WHERE publishedAt IS NOT NULL")
			.create();

		createView(name="activeAuthors")
			.selectStatement(sql="SELECT id, firstName, lastName FROM users WHERE deletedAt IS NULL")
			.create();
	}

	function down() {
		dropView(name="publishedArticles");
		dropView(name="activeAuthors");
	}

}

emailField()

View Helpers Form Object Functions string controller

Builds and returns a string containing an email field form control based on the supplied objectName and property. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
objectName any Yes The variable name of the object to build the form control for.
property string Yes The name of the property to use in the form control.
association string No The name of the association that the property is located on. Used for building nested forms that work with nested properties. If you are building a form with deep nesting, simply pass in a list to the nested object, and Wheels will figure it out.
position string No The position used when referencing a hasMany relationship in the association argument. Used for building nested forms that work with nested properties. If you are building a form with deep nestings, simply pass in a list of positions, and Wheels will figure it out.
label string No useDefaultLabel The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
errorElement string No span HTML tag to wrap the form control with when the object contains errors.
errorClass string No field-with-errors The class name of the HTML tag that wraps the form control when there are errors.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic email field bound to an object property
#emailField(objectName="user", property="emailAddress")#

// 2. Email field with a custom label and a CSS class
#emailField(label="Email Address", objectName="user", property="emailAddress", class="form-control")#

// 3. Nested email field for a contacts association (hasMany)
<cfloop from="1" to="#ArrayLen(account.contacts)#" index="i">
	#emailField(label="Contact Email ##i#", objectName="account", association="contacts", position=i, property="email")#
</cfloop>

emailFieldTag()

View Helpers Form Tag Functions string controller

Builds and returns a string containing an email field form control based on the supplied name. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
name string Yes Name to populate in tag's name attribute.
value string No Value to populate in tag's value attribute.
label string No The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic email field with a name and pre-filled value
#emailFieldTag(name="userEmail", value="hello@example.com")#

// 2. Email field with a label
#emailFieldTag(label="Email Address", name="userEmail", value=params.userEmail)#

// 3. Email field with a CSS class and placeholder passed as extra HTML attributes
#emailFieldTag(name="contactEmail", value="", class="form-control", placeholder="you@example.com")#

end()

Configuration Routing struct mapper

Call this to end a nested routing block or the entire route configuration. This method is chained on a sequence of routing mapper method calls started by mapper().

<cfscript>

mapper()
    .namespace("admin")
        .resources("products")
    .end() // Ends the `namespace` block.

    .scope(package="public")
        .resources(name="products", nested=true)
          .resources("variations")
        .end() // Ends the nested `resources` block.
    .end() // Ends the `scope` block.
.end(); // Ends the `mapper` block.

</cfscript>

endFormTag()

View Helpers General Form Functions string controller

Builds and returns a string containing the closing form tag.

Name Type Required Default Description
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Close a form opened with startFormTag
#startFormTag(action="create")#
    <!--- your form controls --->
#endFormTag()#

// 2. Append a note after the closing form tag
#startFormTag(action="update", method="post")#
    <!--- your form controls --->
#endFormTag(append="<p>All fields are required.</p>")#

// 3. Wrap the closing tag with surrounding markup using prepend and append
#startFormTag(route="userSearch")#
    <!--- your form controls --->
#endFormTag(prepend="</div>", append="</section>")#

enum()

Model Configuration Enum Functions void model

Maps a property to a set of named values (like Rails enums). Generates boolean checker methods (is()), scopes for each value, and validates that the property value is one of the allowed values.

Name Type Required Default Description
property string Yes The name of the model property to map as an enum.
values any Yes Either a comma-delimited list of string values (e.g. "draft,published,archived") or a struct mapping names to stored values (e.g. {low: 0, medium: 1, high: 2}).
// 1. Map a `status` property to a comma-delimited list of allowed string values.
//    Wheels auto-validates that `status` is one of the listed values,
//    creates `isDraft()`, `isPublished()`, and `isArchived()` checker methods,
//    and registers `draft()`, `published()`, and `archived()` query scopes.
component extends="Model" {
	function config() {
		enum(property="status", values="draft,published,archived");
	}
}

// 2. Map a `priority` property using a struct so that the stored database value
//    differs from the human-readable name (0, 1, 2 are stored; low/medium/high are the names).
//    Generated methods: `isLow()`, `isMedium()`, `isHigh()`.
//    Generated scopes:  `model("Task").low()`, `model("Task").medium()`, `model("Task").high()`.
component extends="Model" {
	function config() {
		enum(property="priority", values={low: 0, medium: 1, high: 2});
	}
}

// 3. Using the generated checker methods and scopes at runtime.
//    `isPublished()` returns true/false; `published()` scopes a finder to that status.
post = model("Post").findByKey(key=42);
if (post.isPublished()) {
	writeOutput("This post is live.");
}

// Find all published posts using the auto-generated scope.
publishedPosts = model("Post").published().findAll();

enumInfo()

Model Class Miscellaneous Functions struct model

Returns a struct containing all enum definitions for this model. Each key is the property name, and the value contains values (name-to-stored-value mapping) and names (list of enum names).

// 1. Inspect all enum definitions on the Order model
info = model("Order").enumInfo();
// info -> {
//   status: {
//     property: "status",
//     names: "draft,published,archived",
//     values: {draft: "draft", published: "published", archived: "archived"}
//   }
// }

// 2. List all enum-mapped properties
info = model("Order").enumInfo();
for (propName in info) {
    writeOutput(propName & ": " & info[propName].names);
}
// status: draft,published,archived
// priority: low,medium,high

// 3. Use enum metadata to build a select list for a form
info = model("Order").enumInfo();
statusEnum = info["status"];
for (enumName in listToArray(statusEnum.names)) {
    storedValue = statusEnum.values[enumName];
    writeOutput(enumName & " -> " & storedValue);
}
// draft -> draft
// published -> published
// archived -> archived

env()

Configuration Miscellaneous Functions any controller model mapper migrator migration tabledefinition

Returns the value of an environment variable. Checks application.env (loaded from .env files) first, then falls back to system environment variables (server.system.environment). Returns the default if the variable is not found in either location. named argument default is also accepted for backwards compatibility with pre-rename callers.

Name Type Required Default Description
name string Yes The environment variable name to look up.
defaultValue any No Value to return if the variable is not found. The legacy
// 1. Read a required environment variable
dbUrl = env("DATABASE_URL");
// dbUrl -> "postgres://user:pass@localhost/myapp" (or "" if not set)

// 2. Provide a default when the variable may be absent
smtpHost = env("SMTP_HOST", "localhost");
// smtpHost -> "localhost" when SMTP_HOST is not defined in .env or system env

// 3. Guard application startup based on an environment variable
appSecret = env("APP_SECRET_KEY");
if (!Len(appSecret)) {
	throw(type="App.ConfigError", message="APP_SECRET_KEY must be set.");
}

errorCount()

Model Object Error Functions numeric model

Returns the number of errors this object has associated with it. Specify property or name if you wish to count only specific errors.

Name Type Required Default Description
property string No Specify a property name here if you want to count only errors set on a specific property.
name string No Specify an error name here if you want to count only errors set with a specific error name.
// 1. Check the total number of errors on an object
if (author.errorCount() GTE 10) {
    // Too many errors — bail out early
}

// 2. Check how many errors are associated with a specific property
if (author.errorCount(property="email") gt 0) {
    // The email property has at least one error
}

// 3. Count errors that were set with a specific error name
count = author.errorCount(name="invalidFormat");
// count -> 2 (two errors share the "invalidFormat" name)

errorMessageOn()

View Helpers Error Functions string controller

Returns the error message, if one exists, on the object's property. If multiple error messages exist, the first one is returned.

Name Type Required Default Description
objectName string Yes The variable name of the object to display the error message for.
property string Yes The name of the property to display the error message for.
prependText string No String to prepend to the error message.
appendText string No String to append to the error message.
wrapperElement string No span HTML element to wrap the error message in.
class string No error-message CSS class to set on the wrapper element.
encode boolean No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Display the first error message (if any) on the email property
#errorMessageOn(objectName="user", property="email")#
// -> <span class="error-message">Email is not a valid email address.</span>
// -> (empty string when no error exists on that property)

// 2. Prepend and append custom text around the error message
#errorMessageOn(objectName="user", property="username", prependText="Problem:", appendText="Please try again.")#
// -> <span class="error-message">Problem: Username has already been taken. Please try again.</span>

// 3. Wrap the message in a div with a custom CSS class instead of the default span
#errorMessageOn(objectName="post", property="title", wrapperElement="div", class="field-error")#
// -> <div class="field-error">Title can't be blank.</div>

errorMessagesFor()

View Helpers Error Functions string controller

Builds and returns a list (ul tag with a default class of error-messages) containing all the error messages for all the properties of the object. Returns an empty string if no errors exist.

Name Type Required Default Description
objectName string Yes The variable name of the object to display error messages for.
class string No error-messages CSS class to set on the ul element.
showDuplicates boolean No true Whether or not to show duplicate error messages.
encode boolean No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
includeAssociations boolean No true
// 1. Display all error messages for a user object
#errorMessagesFor(objectName="user")#
// -> <ul class="error-messages"><li>Email is not a valid email address.</li><li>Username can't be blank.</li></ul>
// -> (empty string when the object has no errors)

// 2. Use a custom CSS class on the wrapping ul element
#errorMessagesFor(objectName="user", class="form-errors")#
// -> <ul class="form-errors"><li>Email is not a valid email address.</li></ul>

// 3. Suppress duplicate error messages
#errorMessagesFor(objectName="user", showDuplicates=false)#
// -> <ul class="error-messages"><li>can't be blank.</li></ul>
// (only one "can't be blank." entry even if multiple fields have the same message)

// 4. Include errors from associated objects as well
#errorMessagesFor(objectName="order", includeAssociations=true)#
// -> <ul class="error-messages"><li>Name can't be blank.</li><li>Line items quantity must be greater than zero.</li></ul>

errorsOn()

Model Object Error Functions array model

Returns an array of all errors associated with the supplied property (and error name if passed in).

Name Type Required Default Description
property string Yes Specify the property name to return errors for here.
name string No If you want to return only errors on the property set with a specific error name you can specify it here.
// 1. Get all errors associated with the emailAddress property
errors = user.errorsOn("emailAddress");
// errors -> [{property: "emailAddress", message: "is invalid", name: ""}, ...]

// 2. Get only errors on emailAddress that were set with a specific error name
errors = user.errorsOn(property="emailAddress", name="formatCheck");
// errors -> [{property: "emailAddress", message: "must be a valid email", name: "formatCheck"}]

// 3. Check errors on a property and loop over them
errors = user.errorsOn("username");
for (error in errors) {
    writeOutput(error.message);
}

errorsOnBase()

Model Object Error Functions array model

Returns an array of all errors associated with the object as a whole (not related to any specific property).

Name Type Required Default Description
name string No Specify an error name here to only return errors for that error name.
// 1. Get all general (base) errors for a model object after validation
user = model("User").new(params.user);
user.valid();
errors = user.errorsOnBase();
// errors -> [{property: "", message: "Account has been suspended", name: ""}]

// 2. Filter base errors by a specific error name
user.addErrorToBase(message="Account has been suspended", name="suspended");
user.addErrorToBase(message="Please accept the terms", name="terms");
suspendedErrors = user.errorsOnBase(name="suspended");
// suspendedErrors -> [{property: "", message: "Account has been suspended", name: "suspended"}]

// 3. Check for base errors and display them
errors = user.errorsOnBase();
if (arrayLen(errors)) {
    for (e in errors) {
        writeOutput(e.message);
    }
}

excerpt()

Global Helpers String Functions string controller model mapper migrator migration tabledefinition

Extracts an excerpt from text that matches the first instance of a given phrase.

Name Type Required Default Description
text string Yes The text to extract an excerpt from.
phrase string Yes The phrase to extract.
radius numeric No 100 Number of characters to extract surrounding the phrase.
excerptString string No ... String to replace first and / or last characters with.
// 1. Extract text around a matching phrase with a custom radius
result = excerpt(text="CFWheels is a Rails-like MVC framework for Adobe ColdFusion and Lucee", phrase="framework", radius=5);
// result -> "...MVC framework for Ad..."

// 2. Use the default radius of 100 characters
result = excerpt(text="CFWheels is a powerful MVC framework built for ColdFusion developers who want to move fast.", phrase="powerful");
// result -> "CFWheels is a powerful MVC framework built for ColdFusion developers who want to move fast."

// 3. Customize the excerpt string used to indicate truncated text
result = excerpt(text="The quick brown fox jumps over the lazy dog", phrase="fox", radius=5, excerptString=" [...]");
// result -> " [...]brown fox jumps [...]"

execute()

Migrator Migration Functions void migration

Executes a raw sql query Only available in a migration CFC

Name Type Required Default Description
sql string Yes Arbitrary SQL String
// 1. Run a raw SQL statement during a migration
execute(sql = "UPDATE users SET active = 1 WHERE active IS NULL");

// 2. Create a database view with raw SQL
execute(sql = "CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");

// 3. Use execute() inside up() and down() to apply and reverse a custom SQL change
component extends="wheels.migrator.Migration" {
    function up() {
        execute(sql = "ALTER TABLE orders ADD COLUMN notes TEXT");
    }
    function down() {
        execute(sql = "ALTER TABLE orders DROP COLUMN notes");
    }
}

exists()

Model Class Miscellaneous Functions boolean model

Checks if a record exists in the table. You can pass in either a primary key value to the key argument or a string to the where argument. If you don't pass in either of those, it will simply check if any record exists in the table.

Name Type Required Default Description
key any No Primary key value(s) of the record. Separate with comma if passing in multiple primary key values. Accepts a string, list, or a numeric value.
where string No Maps to the WHERE clause of the query (or HAVING when necessary). The following operators are supported: =, !=, <>, <, <=, >, >=, LIKE, NOT LIKE, IN, NOT IN, IS NULL, IS NOT NULL, AND, and OR (note that the key words need to be written in upper case). You can also use parentheses to group statements. Nested queries not allowed. You do not need to specify the table name(s); Wheels will do that for you.
reload boolean No false Set to true to force Wheels to query the database even though an identical query for this model may have been run in the same request. (The default in Wheels is to get the second query from the model's request-level cache.)
parameterize any No true Set to true to use cfqueryparam on all columns, or pass in a list of property names to use cfqueryparam on those only.
includeSoftDeletes boolean No Set to true to include soft-deleted records in the queries that this method runs.
// 1. Check if any record exists in the table
anyUsers = model("User").exists();

// 2. Check if a record with a specific primary key exists
result = model("User").exists(key=params.key);

// 3. Check if a record matching a WHERE condition exists
joeExists = model("User").exists(where="firstName = 'Joe'");

// 4. Use the result in a conditional
if (model("User").exists(key=params.userId)) {
	// record was found, proceed
}

// 5. Include soft-deleted records in the check
deletedExists = model("User").exists(where="email='old@example.com'", includeSoftDeletes=true);

// 6. If you have a `belongsTo` association from `Comment` to `Post`, you can do a scoped call. (The `hasPost` method below calls `model("Post").exists(comment.postId)` internally.)
comment = model("Comment").findByKey(params.commentId);
commentHasAPost = comment.hasPost();

// 7. If you have a `hasOne` association from `User` to `Profile`, you can do a scoped call. (The `hasProfile` method below calls `model("Profile").exists(where="userId=#user.id#")` internally.)
user = model("User").findByKey(params.userId);
userHasProfile = user.hasProfile();

// 8. If you have a `hasMany` association from `Post` to `Comment`, you can do a scoped call. (The `hasComments` method below calls `model("Comment").exists(where="postId=#post.id#")` internally.)
post = model("Post").findByKey(params.postId);
postHasComments = post.hasComments();

fileField()

View Helpers Form Object Functions string controller

Builds and returns a string containing a file field form control based on the supplied objectName and property. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
objectName any Yes The variable name of the object to build the form control for.
property string Yes The name of the property to use in the form control.
association string No The name of the association that the property is located on. Used for building nested forms that work with nested properties. If you are building a form with deep nesting, simply pass in a list to the nested object, and Wheels will figure it out.
position string No The position used when referencing a hasMany relationship in the association argument. Used for building nested forms that work with nested properties. If you are building a form with deep nestings, simply pass in a list of positions, and Wheels will figure it out.
label string No useDefaultLabel The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
errorElement string No span HTML tag to wrap the form control with when the object contains errors.
errorClass string No field-with-errors The class name of the HTML tag that wraps the form control when there are errors.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic file upload field bound to an object and property
#fileField(objectName="photo", property="imageFile")#

// 2. Provide a custom label for the file field
#fileField(label="Profile Photo", objectName="user", property="avatar")#

// 3. Display file upload fields for a hasMany association using nested properties
<fieldset>
	<legend>Screenshots</legend>
	<cfloop from="1" to="#ArrayLen(site.screenshots)#" index="i">
		#fileField(label="File ##i#", objectName="site", association="screenshots", position=i, property="file")#
		#textField(label="Caption ##i#", objectName="site", association="screenshots", position=i, property="caption")#
	</cfloop>
</fieldset>

fileFieldTag()

View Helpers Form Tag Functions string controller

Builds and returns a string containing a file form control based on the supplied name. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
name string Yes Name to populate in tag's name attribute.
label string No The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic file upload field with a label
#fileFieldTag(name="photo", label="Profile Photo")#

// 2. File upload field with a CSS class and no label
#fileFieldTag(name="attachment", class="upload-input")#

// 3. File upload field with label placement and wrapper HTML
#fileFieldTag(name="resume", label="Upload Resume", labelPlacement="before", prepend="<div class='field'>", append="</div>")#

filterChain()

Controller Configuration Functions array controller

Returns an array of all the filters set on current controller in the order in which they will be executed.

Name Type Required Default Description
type string No all Use this argument to return only before or after filters.
// 1. Get the entire filter chain for the current controller
myFilterChain = filterChain();
// myFilterChain -> array of structs, each with keys: through, type, only, except, arguments
// e.g. [{ through: "checkLogin", type: "before", only: "", except: "" }, ...]

// 2. Get only the before-filters
beforeFilters = filterChain(type="before");
for (f in beforeFilters) {
    writeOutput(f.through);
}

// 3. Get only the after-filters
afterFilters = filterChain(type="after");
writeOutput(arrayLen(afterFilters));

filters()

Controller Configuration Functions void controller

Tells Wheels to run a function before an action is run or after an action has been run.

Name Type Required Default Description
through string Yes Function(s) to execute before or after the action(s).
type string No before Whether to run the function(s) before or after the action(s).
only string No Pass in a list of action names (or one action name) to tell Wheels that the filter function(s) should only be run on these actions.
except string No Pass in a list of action names (or one action name) to tell Wheels that the filter function(s) should be run on all actions except the specified ones.
placement string No append Pass in prepend to prepend the function(s) to the filter chain instead of appending.
// 1. Run `restrictAccess` before every action in this controller (declared inside config()).
filters("restrictAccess");

// 2. Run two before-filters on every action except `home` and `login`.
filters(through="isLoggedIn, checkIPAddress", except="home, login");

// 3. Run `auditLog` after only the `create`, `update`, and `delete` actions.
filters(through="auditLog", type="after", only="create, update, delete");

// 4. Prepend a filter so it runs before any already-registered filters.
filters(through="maintenanceCheck", placement="prepend");

// Note: filter functions must be declared as `private` in the controller
// to prevent them from being routed as public actions.
// Example controller setup:
// component extends="Controller" {
//     function config() {
//         filters("restrictAccess");
//     }
//     private function restrictAccess() {
//         if (!isLoggedIn()) {
//             redirectTo(route="login");
//         }
//     }
// }

findAll()

Model Class Read Functions any model

Returns records from the database table mapped to this model according to the arguments passed in (use the where argument to decide which records to get, use the order argument to set the order in which those records should be returned, and so on). The records will be returned as either a cfquery result set, an array of objects, or an array of structs (depending on what the returnAs argument is set to).

Name Type Required Default Description
where string No Maps to the WHERE clause of the query (or HAVING when necessary). The following operators are supported: =, !=, <>, <, <=, >, >=, LIKE, NOT LIKE, IN, NOT IN, IS NULL, IS NOT NULL, AND, and OR (note that the key words need to be written in upper case). You can also use parentheses to group statements. Nested queries not allowed. You do not need to specify the table name(s); Wheels will do that for you.
order string No Maps to the ORDER BY clause of the query. You do not need to specify the table name(s); Wheels will do that for you.
group string No Maps to the GROUP BY clause of the query. You do not need to specify the table name(s); Wheels will do that for you.
select string No Determines how the SELECT clause for the query used to return data will look. You can pass in a list of the properties (which map to columns) that you want returned from your table(s). If you don't set this argument at all, Wheels will select all properties from your table(s). If you specify a table name (e.g. users.email) or alias a column (e.g. fn AS firstName) in the list, then the entire list will be passed through unchanged and used in the SELECT clause of the query. By default, all column names in tables joined via the include argument will be prepended with the singular version of the included table name.
includeCalculated string No List of calculated property names (declared via property(name="...", sql="...", select=false)) to additively opt into this finder's SELECT clause. Unlike select, this does not replace the default column list — the named calculated properties are merged on top of all default columns, so the rest of the record is still returned. Useful for pulling a select=false computed property back in on a single finder without spelling out every other column. Unknown names throw Wheels.CalculatedPropertyNotFound in development/testing and are ignored in production.
distinct boolean No false Whether to add the DISTINCT keyword to your SELECT clause. Wheels will, when necessary, add this automatically (when using pagination and a hasMany association is used in the include argument, to name one example).
include string No Associations that should be included in the query using INNER or LEFT OUTER joins (which join type that is used depends on how the association has been set up in your model). If all included associations are set on the current model, you can specify them in a list (e.g. department,addresses,emails). You can build more complex include strings by using parentheses when the association is set on an included model, like album(artist(genre)), for example. These complex include strings only work when returnAs is set to query though.
maxRows numeric No -1 Maximum number of records to retrieve. Passed on to the maxRows cfquery attribute. The default, -1, means that all records will be retrieved.
page numeric No 0 If you want to paginate records, you can do so by specifying a page number here. For example, getting records 11-20 would be page number 2 when perPage is kept at the default setting (10 records per page). The default, 0, means that records won't be paginated and that the perPage and count arguments will be ignored.
perPage numeric No 10 When using pagination, you can specify how many records you want to fetch per page here. This argument is only used when the page argument has been passed in.
count numeric No 0 When using pagination and you know in advance how many records you want to paginate through, you can pass in that value here. Doing so will prevent Wheels from running a COUNT query to get this value. This argument is only used when the page argument has been passed in.
handle string No query Handle to use for the query. This is used when you're paginating multiple queries and need to reference them individually in the paginationLinks() function. It's also used to set the name of the query in the debug output (which otherwise defaults to userFindAllQuery for example).
cache any No If you want to cache the query, you can do so by specifying the number of minutes you want to cache the query for here. If you set it to true, the default cache time will be used (60 minutes).
reload boolean No false Set to true to force Wheels to query the database even though an identical query for this model may have been run in the same request. (The default in Wheels is to get the second query from the model's request-level cache.)
parameterize any No true Set to true to use cfqueryparam on all columns, or pass in a list of property names to use cfqueryparam on those only.
returnAs string No query Set to objects to return an array of objects, set to structs to return an array of structs, set to query to return a query result set, or set to 'sql' to return the executed SQL query as a string.
returnIncluded boolean No true When returnAs is set to objects, you can set this argument to false to prevent returning objects fetched from associations specified in the include argument. This is useful when you only need to include associations for use in the WHERE clause only and want to avoid the performance hit that comes with object creation.
callbacks boolean No true Set to false to disable callbacks for this method.
includeSoftDeletes boolean No false Set to true to include soft-deleted records in the queries that this method runs.
useIndex struct No [runtime expression] If you want to specify table index hints, pass in a structure of index names using your model names as the structure keys. Eg: {user="idx_users", post="idx_posts"}. This feature is only supported by MySQL and SQL Server.
dataSource string No [runtime expression] Override the default datasource
// 1. Get all users ordered by last name
users = model("user").findAll(order="lastName ASC");

// 2. Get only 5 users in a random order
fiveRandomUsers = model("user").findAll(maxRows=5, order="random");

// 3. Include a belongsTo association and filter with a WHERE clause
articles = model("article").findAll(include="author", where="published=1", order="createdAt DESC");

// 4. Include a hasMany association in the opposite direction
bobsArticles = model("author").findAll(include="articles", where="firstName='Bob'");

// 5. Use pagination (records 26-50) with a nested include (song belongsTo album, album belongsTo artist)
songs = model("song").findAll(include="album(artist)", page=2, perPage=25);

// 6. Return results as an array of model objects instead of a query
activeUsers = model("user").findAll(where="active=1", order="lastName ASC", returnAs="objects");
for (user in activeUsers) {
	writeOutput(user.firstName & " " & user.lastName);
}

// 7. Return results as an array of structs
userStructs = model("user").findAll(where="active=1", returnAs="structs");

// 8. Use a dynamic finder to get all books released in a certain year
// (same as model("book").findAll(where="releaseYear=#params.year#"))
books = model("book").findAllByReleaseYear(params.year);

// 9. Use a dynamic finder with multiple criteria
// (same as model("book").findAll(where="releaseYear=#params.year# AND type='#params.type#'"))
books = model("book").findAllByReleaseYearAndType("#params.year#,#params.type#");

// 10. Use a scoped call via a hasMany association (calls findAll internally with a where clause)
post = model("post").findByKey(params.postId);
comments = post.comments();

// 11. Use GROUP BY with a calculated property (generates HAVING instead of WHERE)
// Order model has a calculated property: property(name="totalAmount", sql="SUM(amount)")
ids = model("order").findAll(group="productId", where="totalAmount > 1000", select="productId");

// 12. Include soft-deleted records
allUsers = model("user").findAll(includeSoftDeletes=true, order="lastName ASC");

// 13. Cache the query results for 10 minutes
cachedUsers = model("user").findAll(where="active=1", cache=10);

// 14. Return the generated SQL string instead of running the query
sql = model("user").findAll(where="active=1", order="lastName ASC", returnAs="sql");
// sql -> "SELECT ... FROM users WHERE active = 1 ORDER BY last_name ASC"

// 15. Use index hints (MySQL and SQL Server only)
indexes = {
	author="idx_authors_name",
	post="idx_posts_created"
};
posts = model("author").findAll(
	where="firstName LIKE '#params.q#%' OR subject LIKE '#params.q#%'",
	include="posts",
	useIndex=indexes
);

findAllKeys()

Model Class Read Functions string model

Returns all primary key values in a list. In addition to quoted and delimiter you can pass in any argument that findAll() accepts.

Name Type Required Default Description
quoted boolean No false Set to true to enclose each value in single-quotation marks.
delimiter string No , The delimiter character to separate the list items with.
// 1. Get a comma-delimited list of all primary key values for the Artist model
primaryKeyList = model("artist").findAllKeys();
// primaryKeyList -> "1,2,3,4,5"

// 2. Get keys for active artists only, enclosed in single quotes, separated by a pipe
primaryKeyList = model("artist").findAllKeys(quoted=true, delimiter="|", where="active=1");
// primaryKeyList -> "'1'|'3'|'5'"

// 3. Use the result directly in a SQL IN clause for a subsequent query
keyList = model("artist").findAllKeys(quoted=true, where="genreId=7");
albums = model("album").findAll(where="artistId IN (#keyList#)");

findByKey()

Model Class Read Functions any model

Fetches the requested record by primary key and returns it as an object. Returns false if no record is found. You can override this behavior to return a cfquery result set instead, similar to what's described in the documentation for findOne().

Name Type Required Default Description
key any Yes Primary key value(s) of the record. Separate with comma if passing in multiple primary key values. Accepts a string, list, or a numeric value.
select string No Determines how the SELECT clause for the query used to return data will look. You can pass in a list of the properties (which map to columns) that you want returned from your table(s). If you don't set this argument at all, Wheels will select all properties from your table(s). If you specify a table name (e.g. users.email) or alias a column (e.g. fn AS firstName) in the list, then the entire list will be passed through unchanged and used in the SELECT clause of the query. By default, all column names in tables joined via the include argument will be prepended with the singular version of the included table name.
includeCalculated string No List of calculated property names (declared via property(name="...", sql="...", select=false)) to additively opt into this finder's SELECT clause. Unlike select, this does not replace the default column list — the named calculated properties are merged on top of all default columns, so the rest of the record is still returned. Useful for pulling a select=false computed property back in on a single finder without spelling out every other column. Unknown names throw Wheels.CalculatedPropertyNotFound in development/testing and are ignored in production.
include string No Associations that should be included in the query using INNER or LEFT OUTER joins (which join type that is used depends on how the association has been set up in your model). If all included associations are set on the current model, you can specify them in a list (e.g. department,addresses,emails). You can build more complex include strings by using parentheses when the association is set on an included model, like album(artist(genre)), for example. These complex include strings only work when returnAs is set to query though.
handle string No query Handle to use for the query. This is used to set the name of the query in the debug output (which otherwise defaults to userFindOneQuery for example).
cache any No If you want to cache the query, you can do so by specifying the number of minutes you want to cache the query for here. If you set it to true, the default cache time will be used (60 minutes).
reload boolean No false Set to true to force Wheels to query the database even though an identical query for this model may have been run in the same request. (The default in Wheels is to get the second query from the model's request-level cache.)
parameterize any No true Set to true to use cfqueryparam on all columns, or pass in a list of property names to use cfqueryparam on those only.
returnAs string No object Set to objects to return an array of objects, set to structs to return an array of structs, set to query to return a query result set, or set to 'sql' to return the executed SQL query as a string.
callbacks boolean No true Set to false to disable callbacks for this method.
includeSoftDeletes boolean No false Set to true to include soft-deleted records in the queries that this method runs.
dataSource string No [runtime expression] Override the default datasource
// 1. Get the author with the primary key value `99` as an object
auth = model("author").findByKey(99);

// 2. Get an author based on a form/URL value and handle the not-found case
auth = model("author").findByKey(params.key);
if (!isObject(auth)) {
    flashInsert(message="Author #params.key# was not found");
    redirectTo(back=true);
}

// 3. Fetch only selected columns for a record
user = model("user").findByKey(key=params.id, select="id,firstName,email");

// 4. Include a belongsTo association when fetching by key
order = model("order").findByKey(key=params.orderId, include="customer");

// 5. Cache the lookup for 10 minutes and include soft-deleted records
product = model("product").findByKey(key=params.id, cache=10, includeSoftDeletes=true);

// 6. Use a scoped call via a belongsTo association (calls `model("post").findByKey(comment.postId)` internally)
comment = model("comment").findByKey(params.commentId);
post = comment.post();

findEach()

Model Class Read Functions void model

Processes large result sets one record at a time without loading everything into memory. Internally paginates through records and invokes the callback for each individual record. The callback receives a model object (when returnAs is "object") or a struct representing one row.

Name Type Required Default Description
batchSize numeric No 1000 Number of records to load per internal database query. Defaults to 1000.
callback any Yes A function/closure to call for each record. Receives a single argument: the record (object or struct).
where string No Maps to the WHERE clause of the query (or HAVING when necessary). The following operators are supported: =, !=, <>, <, <=, >, >=, LIKE, NOT LIKE, IN, NOT IN, IS NULL, IS NOT NULL, AND, and OR (note that the key words need to be written in upper case). You can also use parentheses to group statements. Nested queries not allowed. You do not need to specify the table name(s); Wheels will do that for you.
order string No Maps to the ORDER BY clause of the query. You do not need to specify the table name(s); Wheels will do that for you.
include string No Associations that should be included in the query using INNER or LEFT OUTER joins (which join type that is used depends on how the association has been set up in your model). If all included associations are set on the current model, you can specify them in a list (e.g. department,addresses,emails). You can build more complex include strings by using parentheses when the association is set on an included model, like album(artist(genre)), for example. These complex include strings only work when returnAs is set to query though.
select string No Determines how the SELECT clause for the query used to return data will look. You can pass in a list of the properties (which map to columns) that you want returned from your table(s). If you don't set this argument at all, Wheels will select all properties from your table(s). If you specify a table name (e.g. users.email) or alias a column (e.g. fn AS firstName) in the list, then the entire list will be passed through unchanged and used in the SELECT clause of the query. By default, all column names in tables joined via the include argument will be prepended with the singular version of the included table name.
parameterize any No Set to true to use cfqueryparam on all columns, or pass in a list of property names to use cfqueryparam on those only.
includeSoftDeletes boolean No false Set to true to include soft-deleted records in the queries that this method runs.
returnAs string No object Whether each record is an "object" (default) or "struct".
// 1. Send a newsletter email to every subscriber one at a time
model("Subscriber").findEach(callback = function(subscriber) {
    sendEmail(
        to = subscriber.email,
        subject = "Monthly Newsletter",
        template = "/emails/newsletter",
        subscriber = subscriber
    );
});

// 2. Process users as structs and write a report entry for each one
model("User").findEach(
    where = "active = 1",
    order = "lastName ASC",
    returnAs = "struct",
    callback = function(user) {
        writeLog("Processing user: #user.firstName# #user.lastName#");
    }
);

// 3. Archive old orders in smaller batches to reduce memory pressure
model("Order").findEach(
    where = "createdAt < '#DateFormat(DateAdd('yyyy', -2, Now()), 'yyyy-mm-dd')#'",
    batchSize = 250,
    callback = function(order) {
        order.archived = true;
        order.save();
    }
);

findFirst()

Model Class Read Functions any model

Fetches the first record ordered by primary key value. Use the property argument to order by something else. Returns a model object.

Name Type Required Default Description
property string No [runtime expression] Name of the property to order by. This argument is also aliased as properties.
// 1. Get the first user record (ordered by primary key ascending)
user = model("User").findFirst();
// Returns the model object with the lowest primary key value, or false if no records exist.

// 2. Get the first user ordered by a specific property
user = model("User").findFirst(property="createdAt");
// Returns the oldest user (lowest createdAt value).

// 3. Get the first active user ordered by last name, then first name
user = model("User").findFirst(properties="lastName,firstName", where="active = 1");
// Equivalent to: ORDER BY lastName ASC, firstName ASC with a WHERE clause applied.
// Returns a model object, or false if no matching record is found.

findInBatches()

Model Class Read Functions void model

Processes large result sets in batches without loading everything into memory at once. The callback receives a query result set (or array of objects/structs) for each batch.

Name Type Required Default Description
batchSize numeric No 500 Number of records per batch. Defaults to 500.
callback any Yes A function/closure to call for each batch. Receives a single argument: the batch (query, array of objects, or array of structs depending on returnAs).
where string No Maps to the WHERE clause of the query (or HAVING when necessary). The following operators are supported: =, !=, <>, <, <=, >, >=, LIKE, NOT LIKE, IN, NOT IN, IS NULL, IS NOT NULL, AND, and OR (note that the key words need to be written in upper case). You can also use parentheses to group statements. Nested queries not allowed. You do not need to specify the table name(s); Wheels will do that for you.
order string No Maps to the ORDER BY clause of the query. You do not need to specify the table name(s); Wheels will do that for you.
include string No Associations that should be included in the query using INNER or LEFT OUTER joins (which join type that is used depends on how the association has been set up in your model). If all included associations are set on the current model, you can specify them in a list (e.g. department,addresses,emails). You can build more complex include strings by using parentheses when the association is set on an included model, like album(artist(genre)), for example. These complex include strings only work when returnAs is set to query though.
select string No Determines how the SELECT clause for the query used to return data will look. You can pass in a list of the properties (which map to columns) that you want returned from your table(s). If you don't set this argument at all, Wheels will select all properties from your table(s). If you specify a table name (e.g. users.email) or alias a column (e.g. fn AS firstName) in the list, then the entire list will be passed through unchanged and used in the SELECT clause of the query. By default, all column names in tables joined via the include argument will be prepended with the singular version of the included table name.
parameterize any No Set to true to use cfqueryparam on all columns, or pass in a list of property names to use cfqueryparam on those only.
includeSoftDeletes boolean No false Set to true to include soft-deleted records in the queries that this method runs.
returnAs string No query Set to "query" (default), "objects", or "structs" for the batch format.
// 1. Process all users in batches of 500 (default), logging each batch
model("User").findInBatches(callback=function(batch) {
	writeOutput("Processing " & batch.recordCount & " users");
});

// 2. Process active orders in batches of 200, filtered with a WHERE clause
model("Order").findInBatches(
	batchSize=200,
	where="status='active'",
	order="createdAt ASC",
	callback=function(batch) {
		// batch is a cfquery result set by default
		for (local.i = 1; local.i <= batch.recordCount; local.i++) {
			writeOutput(batch.orderId[local.i] & ": " & batch.total[local.i]);
		}
	}
);

// 3. Receive each batch as an array of model objects instead of a query
model("User").findInBatches(
	batchSize=100,
	returnAs="objects",
	where="active=1",
	callback=function(batch) {
		for (user in batch) {
			user.sendNewsletter();
		}
	}
);

// 4. Receive each batch as an array of structs
model("Product").findInBatches(
	batchSize=250,
	returnAs="structs",
	select="id,name,price",
	callback=function(batch) {
		for (product in batch) {
			writeOutput(product.name & " costs " & product.price);
		}
	}
);

// 5. Include soft-deleted records while processing in batches
model("User").findInBatches(
	includeSoftDeletes=true,
	callback=function(batch) {
		writeOutput("Batch has " & batch.recordCount & " records (including deleted)");
	}
);

findLastOne()

Model Class Read Functions any model

Fetches the last record ordered by primary key value. Use the property argument to order by something else. Returns a model object. Formerly known as findLast.

Name Type Required Default Description
property string No Name of the property to order by. This argument is also aliased as properties.
// 1. Get the last user record (ordered by primary key descending)
lastUser = model("User").findLastOne();
// Returns a User object for the record with the highest primary key, or false if none exist.

// 2. Get the most recently created post by ordering on a different property
latestPost = model("Post").findLastOne(property="createdAt");
// Returns the Post object with the latest createdAt value.

// 3. Get the last active product, using a where clause alongside the property order
lastActive = model("Product").findLastOne(property="updatedAt", where="isActive = 1");
// Returns the most recently updated active product, or false if none exist.

findOne()

Model Class Read Functions any model

Fetches the first record found based on the WHERE and ORDER BY clauses. With the default settings (i.e. the returnAs argument set to object), a model object will be returned if the record is found and the boolean value false if not. Instead of using the where argument, you can create cleaner code by making use of a concept called Dynamic Finders.

Name Type Required Default Description
where string No Maps to the WHERE clause of the query (or HAVING when necessary). The following operators are supported: =, !=, <>, <, <=, >, >=, LIKE, NOT LIKE, IN, NOT IN, IS NULL, IS NOT NULL, AND, and OR (note that the key words need to be written in upper case). You can also use parentheses to group statements. Nested queries not allowed. You do not need to specify the table name(s); Wheels will do that for you.
order string No Maps to the ORDER BY clause of the query. You do not need to specify the table name(s); Wheels will do that for you.
select string No Determines how the SELECT clause for the query used to return data will look. You can pass in a list of the properties (which map to columns) that you want returned from your table(s). If you don't set this argument at all, Wheels will select all properties from your table(s). If you specify a table name (e.g. users.email) or alias a column (e.g. fn AS firstName) in the list, then the entire list will be passed through unchanged and used in the SELECT clause of the query. By default, all column names in tables joined via the include argument will be prepended with the singular version of the included table name.
includeCalculated string No List of calculated property names (declared via property(name="...", sql="...", select=false)) to additively opt into this finder's SELECT clause. Unlike select, this does not replace the default column list — the named calculated properties are merged on top of all default columns, so the rest of the record is still returned. Useful for pulling a select=false computed property back in on a single finder without spelling out every other column. Unknown names throw Wheels.CalculatedPropertyNotFound in development/testing and are ignored in production.
include string No Associations that should be included in the query using INNER or LEFT OUTER joins (which join type that is used depends on how the association has been set up in your model). If all included associations are set on the current model, you can specify them in a list (e.g. department,addresses,emails). You can build more complex include strings by using parentheses when the association is set on an included model, like album(artist(genre)), for example. These complex include strings only work when returnAs is set to query though.
handle string No query Handle to use for the query. This is used to set the name of the query in the debug output (which otherwise defaults to userFindOneQuery for example).
cache any No If you want to cache the query, you can do so by specifying the number of minutes you want to cache the query for here. If you set it to true, the default cache time will be used (60 minutes).
reload boolean No false Set to true to force Wheels to query the database even though an identical query for this model may have been run in the same request. (The default in Wheels is to get the second query from the model's request-level cache.)
parameterize any No true Set to true to use cfqueryparam on all columns, or pass in a list of property names to use cfqueryparam on those only.
returnAs string No object Set to objects to return an array of objects, set to structs to return an array of structs, set to query to return a query result set, or set to 'sql' to return the executed SQL query as a string.
includeSoftDeletes boolean No false Set to true to include soft-deleted records in the queries that this method runs.
useIndex struct No [runtime expression] If you want to specify table index hints, pass in a structure of index names using your model names as the structure keys. Eg: {user="idx_users", post="idx_posts"}. This feature is only supported by MySQL and SQL Server.
dataSource string No [runtime expression] Override the default datasource
// 1. Get the most recent order as an object from the database
order = model("Order").findOne(order="datePurchased DESC");

// 2. Use a where clause to find the first user with a specific email address
user = model("User").findOne(where="email='someone@example.com'");

// 3. Use a dynamic finder to get the first person with the last name Smith.
// Equivalent to: model("User").findOne(where="lastName='Smith'")
person = model("User").findOneByLastName("Smith");

// 4. Use a dynamic finder to match on two columns.
// Equivalent to: model("User").findOne(where="email='someone@example.com' AND password='mypass'")
user = model("User").findOneByEmailAndPassword("someone@example.com", "mypass");

// 5. Return false when no matching record is found (the default returnAs="object" behavior)
user = model("User").findOne(where="email='unknown@example.com'");
if (!isObject(user)) {
    writeOutput("No user found.");
}

// 6. Return as a query result set instead of an object
userQuery = model("User").findOne(where="role='admin'", returnAs="query");

// 7. Use a scoped call via a hasOne association from User to Profile.
// The profile() method calls model("Profile").findOne(where="userId=#user.id#") internally.
user = model("User").findByKey(params.userId);
profile = user.profile();

// 8. Use a scoped call via a hasMany association from Post to Comment.
// The findOneComment() method calls model("Comment").findOne(where="postId=#post.id#") internally.
post = model("Post").findByKey(params.postId);
comment = post.findOneComment(where="approved=1");

flash()

Controller Flash Functions any controller

Returns the value of a specific key in the Flash (or the entire Flash as a struct if no key is passed in).

Name Type Required Default Description
key string No The key to get the value for.
// 1. Get the current value of a specific key in the Flash
notice = flash("notice");
// notice -> "Your profile was updated successfully."

// 2. Get the entire Flash as a struct when no key is passed
flashContents = flash();
// flashContents -> {notice: "Record saved.", error: "Something went wrong."}

// 3. Check for a key before reading it to avoid an empty-string fallback
if (flashKeyExists("error")) {
    errorMessage = flash("error");
}

flashClear()

Controller Flash Functions void controller

Deletes everything from the Flash.

// 1. Clear all flash data
flashClear();

// 2. Insert some messages, then clear them all before redirecting
flashInsert(notice="Record saved.");
flashInsert(warning="Check your settings.");
// Oops — wipe everything and start fresh
flashClear();
// flash() is now an empty struct: {}

// 3. Clear flash conditionally inside a controller action
function checkout() {
    if (!isLoggedIn()) {
        flashClear();
        flashInsert(error="You must be logged in to check out.");
        redirectTo(action="login");
    }
}

flashCount()

Controller Flash Functions numeric controller

Returns how many keys exist in the Flash.

// 1. Check how many keys are currently in the Flash
count = flashCount();
// count -> 0 (Flash is empty), or a positive integer when keys exist

// 2. Only render a Flash notice section when there is something to show
if (flashCount()) {
    writeOutput("You have " & flashCount() & " flash message(s).");
}

// 3. Use alongside flashIsEmpty() — flashCount() powers the isEmpty check
flashInsert(notice="Saved successfully", warning="Check your email");
count = flashCount();
// count -> 2

flashDelete()

Controller Flash Functions any controller

Deletes a specific key from the Flash. Returns true if the key exists.

Name Type Required Default Description
key string Yes The key to delete
// 1. Delete a key from the Flash
flashDelete(key="errorMessage");

// 2. Check the return value — true if the key existed, false if it did not
wasPresent = flashDelete(key="notice");
// wasPresent -> true  (key existed and was removed)
// wasPresent -> false (key did not exist in the Flash)

// 3. Conditionally act on whether the key was actually removed
if (flashDelete(key="warning")) {
    // key existed; it has now been removed from the Flash
} else {
    // key was not present; nothing was changed
}

flashInsert()

Controller Flash Functions void controller

Inserts a new key / value into the Flash.

// 1. Insert a single key / value into the Flash
flashInsert(notice="Your profile has been updated.");

// 2. Insert multiple keys at once
flashInsert(success="Account created.", hint="Check your email to confirm.");

// 3. Read back a Flash value in the next action or view
// (After a redirect, in the destination action or its view:)
msg = flash("notice");
// msg -> "Your profile has been updated."

flashIsEmpty()

Controller Flash Functions boolean controller

Returns whether or not the Flash is empty.

// 1. Check whether the Flash is empty before rendering a notice area
if (!flashIsEmpty()) {
    writeOutput(flash("notice"));
}

// 2. Insert a message and confirm the Flash is no longer empty
flashInsert(notice="Record saved successfully.");
empty = flashIsEmpty();
// empty -> false

// 3. After clearing the Flash, confirm it is empty again
flashClear();
empty = flashIsEmpty();
// empty -> true

flashKeep()

Controller Flash Functions void controller

Make the entire Flash or specific key in it stick around for one more request.

Name Type Required Default Description
key string No
// 1. Keep the entire Flash for the next request
flashKeep();

// 2. Keep the "error" key in the Flash for the next request
flashKeep("error");

// 3. Keep both the "error" and "success" keys in the Flash for the next request
flashKeep("error,success");

flashKeyExists()

Controller Flash Functions boolean controller

Checks if a specific key exists in the Flash.

Name Type Required Default Description
key string Yes The key to check.
// 1. Check for an "error" key before reading it
if (flashKeyExists("error")) {
    errorMessage = flash("error");
}

// 2. Conditionally display a success notice
if (flashKeyExists("success")) {
    writeOutput(flash("success"));
}

// 3. Guard before deleting a specific flash key
if (flashKeyExists("notice")) {
    flashDelete("notice");
}

flashMessages()

View Helpers Miscellaneous Functions string controller

Displays a marked-up listing of messages that exist in the Flash.

Name Type Required Default Description
keys string No The key (or list of keys) to show the value for. You can also use the key argument instead for better readability when accessing a single key.
class string No flash-messages HTML class to set on the div element that contains the messages.
includeEmptyContainer boolean No false Includes the div container even if the Flash is empty.
encode boolean No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Display all Flash messages in a view
// In the controller action:
flashInsert(success="Your post was successfully submitted.");
flashInsert(alert="Don't forget to tweet about this post!");
flashInsert(error="This is an error message.");

// In the layout or view:
writeOutput(flashMessages());

// Generates (keys sorted alphabetically):
// <div class="flash-messages">
//   <p class="alert-message">Don't forget to tweet about this post!</p>
//   <p class="error-message">This is an error message.</p>
//   <p class="success-message">Your post was successfully submitted.</p>
// </div>


// 2. Show only a single Flash key using the `key` alias
writeOutput(flashMessages(key="success"));

// Generates:
// <div class="flash-messages">
//   <p class="success-message">Your post was successfully submitted.</p>
// </div>


// 3. Show a specific set of keys in a defined order using `keys`
writeOutput(flashMessages(keys="success,alert"));

// Generates (in the order supplied, not alphabetically):
// <div class="flash-messages">
//   <p class="success-message">Your post was successfully submitted.</p>
//   <p class="alert-message">Don't forget to tweet about this post!</p>
// </div>


// 4. Always render the container div, even when the Flash is empty
writeOutput(flashMessages(includeEmptyContainer=true));

// Generates:
// <div class="flash-messages"></div>


// 5. Use a custom CSS class on the outer container
writeOutput(flashMessages(class="notifications"));

// Generates:
// <div class="notifications">
//   <p class="alert-message">Don't forget to tweet about this post!</p>
//   <p class="error-message">This is an error message.</p>
//   <p class="success-message">Your post was successfully submitted.</p>
// </div>

float()

Migrator Table Definition Functions any tabledefinition

adds float columns to table definition

Name Type Required Default Description
columnNames string No
default any No
allowNull boolean No true
// 1. Add a single float column to a new table
t.float("price");

// 2. Add a float column with a default value
t.float(columnNames="rating", default="0.0");

// 3. Add multiple float columns at once
t.float("latitude,longitude");

// 4. Add a float column that does not allow NULL values
t.float(columnNames="score", allowNull=false);

// 5. Use float() within a createTable migration
t = createTable("measurements");
t.float("temperature");
t.float(columnNames="humidity,pressure", default="0.0");
t.timestamps();
t.create();

forgetVersion()

Migrator General Functions struct migrator

Removes a row from wheels_migrator_versions without running down(). Only orphan versions (those with no matching local file) can be forgotten — for legitimate rollbacks, use migrate down. Returns: {success, removed, message}

Name Type Required Default Description
version string Yes The version string to forget (digits only after sanitisation).

generateUUID()

Global Helpers UUID Functions string controller model mapper migrator migration tabledefinition

Generates a 36-character UUID compatible with SQL Server's uniqueidentifier.

// 1. Generate a UUID and store it in a variable
newId = generateUUID();
// newId -> "550e8400-e29b-41d4-a716-446655440000" (36-character UUID)

// 2. Use generateUUID() to assign a unique identifier before saving a record
post = model("Post").new(title="Hello World");
post.externalId = generateUUID();
post.save();

// 3. Generate a UUID compatible with SQL Server's uniqueidentifier column
// Useful when inserting records that need a GUID primary key
token = generateUUID();
// token -> "a1b2c3d4-e5f6-7890-abcd-ef1234567890"

get()

Configuration Miscellaneous Functions any controller model migrator migration tabledefinition

Returns the current setting for the supplied Wheels setting or the current default for the supplied Wheels function argument.

Name Type Required Default Description
name string Yes Variable name to get setting for.
functionName string No Function name to get setting for.
// 1. Get the current value of a global Wheels setting
setting = get("tableNamePrefix");
// setting -> "" (or whatever prefix has been configured)

// 2. Get the current value of a different global setting
dsName = get("dataSourceName");
// dsName -> "myAppDB"

// 3. Get the default for a specific function argument
// (useful for inspecting function-level defaults set via set())
msg = get(functionName="validatesConfirmationOf", name="message");
// msg -> "[property] should match confirmation"

get()

Configuration Routing struct mapper

Create a route that matches a URL requiring an HTTP GET method. We recommend only using this matcher to expose actions that display data. See post, patch, delete, and put for matchers that are appropriate for actions that change data in your database.

Name Type Required Default Description
name string No Camel-case name of route to reference when build links and form actions (e.g., blogPost).
pattern string No Overrides the URL pattern that will match the route. The default value is a dasherized version of name (e.g., a name of blogPost generates a pattern of blog-post).
to string No Set controller##action combination to map the route to. You may use either this argument or a combination of controller and action.
controller string No Map the route to a given controller. This must be passed along with the action argument.
action string No Map the route to a given action within the controller. This must be passed along with the controller argument.
package string No Indicates a subfolder that the controller will be referenced from (but not added to the URL pattern). For example, if you set this to admin, the controller will be located at admin/YourController.cfc, but the URL path will not contain admin/.
on string No If this route is within a nested resource, you can set this argument to member or collection. A member route contains a reference to the resource's key, while a collection route does not.
redirect string No Redirect via 302 to this URL when this route is matched. Has precedence over controller/action. Use either an absolute link like /about/, or a full canonical link.
<cfscript>

mapper()
    // 1. Basic GET route using the `to` shorthand (controller##action)
    // Route name:  post
    // Example URL: /posts/my-post-title
    // Controller:  Posts
    // Action:      show
    .get(name="post", pattern="posts/[slug]", to="posts##show")

    // 2. Route using separate `controller` and `action` arguments
    // Route name:  posts
    // Example URL: /posts
    // Controller:  Posts
    // Action:      index
    .get(name="posts", controller="posts", action="index")

    // 3. Custom URL pattern that differs from the route name
    // Route name:  authors
    // Example URL: /the-scribes
    // Controller:  Authors
    // Action:      index
    .get(name="authors", pattern="the-scribes", to="authors##index")

    // 4. Package (subfolder) scoping — keeps the package out of the URL
    // Route name:  commerceCart
    // Example URL: /cart
    // Controller:  commerce.Carts
    // Action:      show
    .get(name="cart", to="carts##show", package="commerce")

    // 5. Multi-line format for readability, with package scoping
    // Route name:  extranetEditProfile
    // Example URL: /profile/edit
    // Controller:  extranet.Profiles
    // Action:      edit
    .get(
        name="editProfile",
        pattern="profile/edit",
        to="profiles##edit",
        package="extranet"
    )

    // 6. Permanent redirect — useful for renamed or moved URLs
    // Example URL: /old-about  ->  302 redirect to /about
    .get(name="oldAbout", pattern="old-about", redirect="/about")

    // 7. GET routes scoped inside a nested resource
    .resources(name="users", nested=true)
        // Route name:  activatedUsers
        // Example URL: /users/activated
        // Controller:  Users
        // Action:      activated
        .get(name="activated", to="users##activated", on="collection")

        // Route name:  preferencesUser
        // Example URL: /users/391/preferences
        // Controller:  Preferences
        // Action:      index
        .get(name="preferences", to="preferences##index", on="member")
    .end()
.end();

</cfscript>

getAvailableMigrations()

Migrator General Functions array migrator

Searches db/migrate folder for migrations. Whilst you can use this in your application, the recommended usage is via either the CLI or the provided GUI interface $getVersionsPreviouslyMigrated). Callers that already hold the list (doctor, info, migrateTo) pass it through to avoid re-running the tracking-table probe chain; when empty it is computed here.

Name Type Required Default Description
path string No [runtime expression] Path to Migration Files: defaults to /app/migrator/migrations/
previousMigrationList string No Optional precomputed applied-versions list (from
// 1. Get all available migrations and find the latest version
migrations = application.wheels.migrator.getAvailableMigrations();

if (arrayLen(migrations)) {
    latestVersion = migrations[arrayLen(migrations)].version;
} else {
    latestVersion = 0;
}

// 2. List pending (not yet run) migrations
migrations = application.wheels.migrator.getAvailableMigrations();

for (migration in migrations) {
    if (migration.status != "migrated") {
        writeOutput(migration.version & " - " & migration.name);
    }
}

// 3. Use a custom migrations path
migrations = application.wheels.migrator.getAvailableMigrations(path=expandPath("/app/db/migrate/"));

getCurrentMigrationVersion()

Migrator General Functions string migrator

Returns current database version. Whilst you can use this in your application, the recommended usage is via either the CLI or the provided GUI interface

// 1. Get current database version
currentVersion = application.wheels.migrator.getCurrentMigrationVersion();
// currentVersion -> "20240315120000"  (timestamp-style version string, or "0" if no migrations have run)

// 2. Display version status in a maintenance view
currentVersion = application.wheels.migrator.getCurrentMigrationVersion();
if (currentVersion == "0") {
    writeOutput("No migrations have been applied yet.");
} else {
    writeOutput("Database is at version: " & currentVersion);
}

getEmails()

Controller Miscellaneous Functions array controller

Primarily used for testing to get information about emails sent during the request.

// 1. Assert that exactly one email was sent during the action (in a test)
processSignup();
emails = getEmails();
assert("arrayLen(emails) eq 1");
assert("emails[1].to eq 'newuser@example.com'");
assert("emails[1].subject eq 'Welcome!'");

// 2. Inspect all emails sent during a request
emails = getEmails();
for (email in emails) {
	writeOutput(email.to & " — " & email.subject);
}

// 3. Return an empty array when no emails were sent
emails = getEmails();
// emails -> []

getFiles()

Controller Miscellaneous Functions array controller

Primarily used for testing to get information about files sent during the request.

// 1. Assert that exactly one file was sent during the action (in a test)
processDownload();
files = getFiles();
assert("arrayLen(files) eq 1");
assert("files[1].name eq 'report.pdf'");

// 2. Inspect all files sent during a request
files = getFiles();
for (file in files) {
	writeOutput(file.name & " — " & file.type);
}

// 3. Return an empty array when no files were sent
files = getFiles();
// files -> []

getRedirect()

Controller Miscellaneous Functions struct controller

Primarily used for testing to establish whether the current request has performed a redirect.

// 1. Assert that a redirect was performed to a specific URL (in a test)
processDelete();
redirect = getRedirect();
assert("structCount(redirect) gt 0");
assert("redirect.url eq '/users'");

// 2. Inspect the full redirect struct after an action runs
submitLogin();
redirect = getRedirect();
// redirect.url        -> "/dashboard"
// redirect.statusCode -> 302
// redirect.addToken   -> false

// 3. Confirm no redirect was performed (action rendered a view instead)
showProfile();
redirect = getRedirect();
// redirect -> {}

getRoutes()

any mapper

getTableNamePrefix()

Model Class Miscellaneous Functions string model

Returns the table name prefix set for the table.

// 1. Use the table name prefix when running a custom query inside a model method
function getDisabledUsers() {
	local.q = queryExecute(
		"SELECT * FROM #this.getTableNamePrefix()#users WHERE disabled = 1",
		[],
		{datasource: get("dataSourceName")}
	);
	return local.q;
}

// 2. Log the configured prefix to verify model setup
prefix = model("User").getTableNamePrefix();
// prefix -> "app_" (or "" if none is set)

group()

Configuration Routing struct mapper

Group routes together with shared attributes like path prefix, name prefix, and constraints without implying a controller package or namespace. Unlike namespace() (which maps to a subfolder and URL prefix) or package() (which maps to a subfolder), group() is a pure organizational grouping mechanism.

Name Type Required Default Description
name string No Name to prepend to child route names for use when building links, forms, and other URLs.
path string No URL path prefix to apply to all child routes.
constraints struct No Variable patterns (regex constraints) to apply to all child routes.
callback any No A callback function to define nested routes within this group. If provided, the group is automatically closed when the callback completes.
<cfscript>

// 1. Group routes under a shared path prefix (open/close style)
mapper()
    .group(path="admin")
        // Route URL: /admin/dashboard
        .get(name="dashboard", to="dashboard##index")
        // Route URL: /admin/reports
        .get(name="reports", to="reports##index")
    .end()
.end();

// 2. Group with both a path prefix and a name prefix
mapper()
    .group(path="account", name="account")
        // Route name:  accountSettings
        // Example URL: /account/settings
        .get(name="settings", to="settings##show")

        // Route name:  accountBilling
        // Example URL: /account/billing
        .get(name="billing", to="billing##show")
    .end()
.end();

// 3. Group with regex constraints applied to all child routes
mapper()
    .group(path="products", constraints={id: "\d+"})
        // Only matches numeric :id segments
        .get(name="productShow", pattern="[id]", to="products##show")
        .put(name="productUpdate", pattern="[id]", to="products##update")
    .end()
.end();

// 4. Group using a callback function (auto-closes the group)
mapper()
    .group(
        path    = "reports",
        name    = "report",
        callback = function(mapper) {
            // Route name:  reportSales
            // Example URL: /reports/sales
            mapper.get(name="sales", to="reports##sales");

            // Route name:  reportExpenses
            // Example URL: /reports/expenses
            mapper.get(name="expenses", to="reports##expenses");
        }
    )
.end();

</cfscript>

h()

View Helpers Sanitization Functions string controller

Encodes a value for safe HTML output. Use in templates to prevent XSS: #h(user.name)# instead of #user.name#.

Name Type Required Default Description
value any Yes The value to encode for HTML output. Converted to string if not already.
// 1. Safely output user-supplied text in a view template
writeOutput(h(user.name));
// If user.name is "<script>alert('xss')</script>", outputs the
// HTML-encoded form: &lt;script&gt;alert(&##x27;xss&##x27;)&lt;/script&gt;

// 2. Encode a variable inline in a cfoutput block
//   Instead of: <cfoutput>##user.bio##</cfoutput>
//   Use:        <cfoutput>##h(user.bio)##</cfoutput>
encodedBio = h(user.bio);

// 3. Encode a non-string value (converted to string automatically)
rating = 4.5;
writeOutput(h(rating));
// rating -> "4.5"

hasChanged()

Model Object Change Functions boolean model

Returns true if the specified property (or any if none was passed in) has been changed but not yet saved to the database. Will also return true if the object is new and no record for it exists in the database.

Name Type Required Default Description
property string No Name of property to check for change.
// 1. Check if a specific property has changed before saving
member = model("member").findByKey(params.memberId);
member.email = params.newEmail;

if (member.hasChanged("email")) {
    // Send a confirmation email before committing the change
    sendEmailChangeNotification(member);
}

// 2. Check if any property has changed (no argument)
user = model("User").findByKey(params.userId);
user.setProperties(params.user);

if (user.hasChanged()) {
    // At least one property differs from the persisted state
    user.save();
}

// 3. Use the dynamic shorthand — automatically generated per property
order = model("Order").findByKey(params.orderId);
order.status = "shipped";

if (order.statusHasChanged()) {
    // Equivalent to: order.hasChanged("status")
    notifyCustomer(order);
}

// 4. New (unsaved) objects always return true — no persisted record exists yet
newPost = model("Post").new(title="Hello");
writeOutput(newPost.hasChanged()); // -> true

hasErrors()

Model Object Error Functions boolean model

Returns true if the object has any errors. You can also limit to only check a specific property or name for errors.

Name Type Required Default Description
property string No Name of the property to check if there are any errors set on.
name string No Error name to check if there are any errors set with.
// 1. Check if a post object has any errors at all
if (post.hasErrors()) {
    // Redirect user back to the form to correct errors
}

// 2. Check if a specific property has errors
if (post.hasErrors(property="title")) {
    // The title field has at least one error
}

// 3. Check if any errors were set with a specific name
if (post.hasErrors(name="uniquenessViolation")) {
    // Handle uniqueness error specifically
}

hasMany()

Model Configuration Association Functions void model

Sets up a hasMany association between this model and the specified one.

Name Type Required Default Description
name string Yes Gives the association a name that you refer to when working with the association (in the include argument to findAll, to name one example).
modelName string No Name of associated model (usually not needed if you follow Wheels conventions because the model name will be deduced from the name argument).
foreignKey string No Foreign key property name (usually not needed if you follow Wheels conventions since the foreign key name will be deduced from the name argument).
joinKey string No Column name to join to if not the primary key (usually not needed if you follow Wheels conventions since the join key will be the table's primary key/keys).
joinType string No outer Use to set the join type when joining associated tables. Possible values are inner (for INNER JOIN) and outer (for LEFT OUTER JOIN).
dependent string No false Defines how to handle dependent model objects when you delete an object from this model. delete / deleteAll deletes the record(s) (deleteAll bypasses object instantiation). remove / removeAll sets the forein key field(s) to NULL (removeAll bypasses object instantiation).
shortcut string No Set this argument to create an additional dynamic method that gets the object(s) from the other side of a many-to-many association.
through string No [runtime expression] Set this argument if you need to override Wheels conventions when using the shortcut argument. Accepts a list of two association names representing the chain from the opposite side of the many-to-many relationship to this model.
as string No Set this argument to declare a polymorphic hasMany association. The child model stores the parent type in a {as}Type column alongside the foreign key {as}Id.
// 1. Basic usage – a Post has many comments (foreign key `postId` lives on the `comments` table)
// In models/Post.cfc config()
hasMany("comments");

// 2. Set up a many-to-many shortcut so readers can access publications directly
// In models/Reader.cfc config()
hasMany(name="subscriptions", shortcut="publications");

// 3. Automatically delete all associated comments (bypassing object instantiation) when the parent is deleted
// In models/Post.cfc config()
hasMany(name="comments", dependent="deleteAll");

// 4. Instantiate and call each comment's beforeDelete callback when deleting dependents
// In models/Post.cfc config()
hasMany(name="comments", dependent="delete");

// 5. Override the many-to-many shortcut chain when association names differ from model names
// In models/Customer.cfc config()
hasMany(name="subscriptions", shortcut="magazines", through="publication,subscriptions");
// In models/Subscription.cfc config()
belongsTo("customer");
belongsTo("publication");
// In models/Publication.cfc config()
hasMany("subscriptions");

// 6. Specify a custom foreign key when not following Wheels naming conventions
// In models/Author.cfc config()
hasMany(name="articles", foreignKey="writtenByAuthorId");

// 7. Use an inner join instead of the default outer join when including the association
// In models/Category.cfc config()
hasMany(name="products", joinType="inner");

// 8. Polymorphic hasMany – a model acts as a parent for a shared `comments` child model
// In models/Photo.cfc config() (the `as` value matches the `polymorphic` interface name on the child)
hasMany(name="comments", as="commentable");
// In models/Comment.cfc config()
belongsTo(name="commentable", polymorphic=true);

hasManyCheckBox()

View Helpers Form Association Functions string controller

Used as a shortcut to output the proper form elements for an association. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
objectName string Yes Name of the variable containing the parent object to represent with this form field.
association string Yes Name of the association set in the parent object to represent with this form field.
keys string Yes Primary keys associated with this form field. Note that these keys should be listed in the order that they appear in the database table.
label string No The label text to use in the form control.
labelPlacement string No Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
errorElement string No HTML tag to wrap the form control with when the object contains errors.
errorClass string No The class name of the HTML tag that wraps the form control when there are errors.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
id string No Optional. Explicit ID for the generated checkbox input. If not provided, an ID will be generated automatically.
// 1. Show check boxes for associating authors with the current book
<cfloop query="authors">
    #hasManyCheckBox(
        label=authors.fullName,
        objectName="book",
        association="bookAuthors",
        keys="#book.key()#,#authors.id#"
    )#
</cfloop>

// 2. Wrap each checkbox and label in a div using prepend/append
<cfloop query="authors">
    #hasManyCheckBox(
        label=authors.fullName,
        labelPlacement="after",
        objectName="book",
        association="bookAuthors",
        keys="#book.key()#,#authors.id#",
        prepend="<div class=""author-option"">",
        append="</div>"
    )#
</cfloop>

// 3. Supply an explicit ID and custom error styling
<cfloop query="tags">
    #hasManyCheckBox(
        label=tags.name,
        objectName="post",
        association="postTags",
        keys="#post.key()#,#tags.id#",
        id="tag-#tags.id#",
        errorElement="span",
        errorClass="field-error"
    )#
</cfloop>

hasManyRadioButton()

View Helpers Form Association Functions string controller

Used as a shortcut to output the proper form elements for an association. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
objectName string Yes Name of the variable containing the parent object to represent with this form field.
association string Yes Name of the association set in the parent object to represent with this form field.
property string Yes Name of the property in the child object to represent with this form field.
keys string Yes Primary keys associated with this form field. Note that these keys should be listed in the order that they appear in the database table.
tagValue string Yes The value of the radio button when selected.
checkIfBlank boolean No false Whether or not to check this form field as a default if there is a blank value set for the property.
label string No The label text to use in the form control.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Show radio buttons for selecting a default address for the current author (loops over a query of addresses)
<cfoutput>
	<cfloop query="addresses">
		#hasManyRadioButton(
			objectName="author",
			association="addresses",
			property="isDefault",
			keys="#author.key()#,#addresses.id#",
			tagValue="1",
			label=addresses.title
		)#
	</cfloop>
</cfoutput>

// 2. Same loop, but mark the radio button as checked when the property is blank (no default set yet)
<cfoutput>
	<cfloop query="addresses">
		#hasManyRadioButton(
			objectName="author",
			association="addresses",
			property="isDefault",
			keys="#author.key()#,#addresses.id#",
			tagValue="1",
			checkIfBlank=true,
			label=addresses.title
		)#
	</cfloop>
</cfoutput>

hasOne()

Model Configuration Association Functions void model

Sets up a hasOne association between this model and the specified one.

Name Type Required Default Description
name string Yes Gives the association a name that you refer to when working with the association (in the include argument to findAll, to name one example).
modelName string No Name of associated model (usually not needed if you follow Wheels conventions because the model name will be deduced from the name argument).
foreignKey string No Foreign key property name (usually not needed if you follow Wheels conventions since the foreign key name will be deduced from the name argument).
joinKey string No Column name to join to if not the primary key (usually not needed if you follow Wheels conventions since the join key will be the table's primary key/keys).
joinType string No outer Use to set the join type when joining associated tables. Possible values are inner (for INNER JOIN) and outer (for LEFT OUTER JOIN).
dependent string No false Defines how to handle dependent model objects when you delete an object from this model. delete / deleteAll deletes the record(s) (deleteAll bypasses object instantiation). remove / removeAll sets the forein key field(s) to NULL (removeAll bypasses object instantiation).
as string No Set this argument to declare a polymorphic hasOne association. The child model stores the parent type in a {as}Type column alongside the foreign key {as}Id.
// 1. Specify that instances of this model have one profile. (The associated model's table, not the current one, should have the foreign key column.)
hasOne("profile");

// 2. Same as above but setting `joinType` to `inner`, meaning this model should always have a matching record in the `profiles` table.
hasOne(name="profile", joinType="inner");

// 3. Automatically delete the associated `profile` record whenever this object is deleted.
hasOne(name="profile", dependent="delete");

// 4. Declare a polymorphic `hasOne` association so that multiple models can each have one image via a shared interface.
hasOne(name="image", as="imageable");

hasProperty()

Model Object Miscellaneous Functions boolean model

Returns true if the specified property name exists on the model.

Name Type Required Default Description
property string Yes Name of property to inspect.
// 1. Check whether a property exists on a new object after setting it
employee = model("Employee").new();
employee.firstName = "Jane";
employee.hasProperty("firstName"); // -> true
employee.hasProperty("salary");    // -> false (not set on this object)

// 2. Use the equivalent dynamic method (has<PropertyName>)
employee.hasFirstName(); // -> true
employee.hasSalary();    // -> false

// 3. Guard logic before accessing a property
user = model("User").findOne(where="email='jane@example.com'");
if (user.hasProperty("avatarUrl")) {
    writeOutput(user.avatarUrl);
}

hAttr()

View Helpers Sanitization Functions string controller

Encodes a value for safe use inside an HTML attribute. Use when building attribute values manually: <div title="#hAttr(user.bio)#">.

Name Type Required Default Description
value any Yes The value to encode for HTML attribute context.
// 1. Safely encode a user-supplied string inside an HTML attribute
userBio = "Say ""hello"" & <wave>";
writeOutput('<div title="#hAttr(userBio)#">Hover me</div>');
<!--- Renders: <div title="Say &#x22;hello&#x22; &amp; &lt;wave&gt;">Hover me</div> --->

// 2. Use directly in a view template to prevent XSS in attribute values
writeOutput('<input type="text" placeholder="#hAttr(params.search)#">');

health()

Configuration Routing struct mapper

Register a health check route at /health (or a custom path). Returns a JSON response with status and timestamp by default, or delegates to a custom controller action. This is useful for container orchestration (Kubernetes liveness/readiness probes), load balancer health checks, and monitoring tools.

Name Type Required Default Description
to string No wheels#health Set controller##action combination for a custom health check handler. If not provided, a default handler returns {"status":"ok","timestamp":"..."}.
path string No health Override the URL path. Defaults to "health".
name string No health Override the route name. Defaults to "health".
<cfscript>

mapper()
    // 1. Register the default health check route at /health.
    // Responds with {"status":"ok","timestamp":"..."} — no controller needed.
    .health()

    .root(to="home##index")
    .wildcard()
.end();

// 2. Override the URL path and route name.
// Accessible at /healthz instead of /health.
mapper()
    .health(path="healthz", name="healthz")
    .root(to="home##index")
.end();

// 3. Delegate to a custom controller action for advanced health checks
// (e.g. database ping, cache connectivity).
mapper()
    .health(to="system##health")
    .root(to="home##index")
.end();

</cfscript>

hiddenField()

View Helpers Form Object Functions string controller

Builds and returns a string containing a hidden field form control based on the supplied objectName and property. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
objectName any Yes The variable name of the object to build the form control for.
property string Yes The name of the property to use in the form control.
association string No The name of the association that the property is located on. Used for building nested forms that work with nested properties. If you are building a form with deep nesting, simply pass in a list to the nested object, and Wheels will figure it out.
position string No The position used when referencing a hasMany relationship in the association argument. Used for building nested forms that work with nested properties. If you are building a form with deep nestings, simply pass in a list of positions, and Wheels will figure it out.
encode boolean No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic usage: embed the user's id as a hidden field
#hiddenField(objectName="user", property="id")#
// -> <input type="hidden" id="user-id" name="user[id]" value="42">

// 2. Carry a token value using a class attribute for JavaScript hooks
#hiddenField(objectName="user", property="csrfToken", class="js-token")#
// -> <input type="hidden" id="user-csrf-token" name="user[csrfToken]" class="js-token" value="abc123">

// 3. Nested form — pass the parent's id through a hasMany association
#hiddenField(objectName="order", property="id", association="lineItems", position="1")#
// -> <input type="hidden" id="order-line-items-1-id" name="order[lineItems][1][id]" value="7">

hiddenFieldTag()

View Helpers Form Tag Functions string controller

Builds and returns a string containing a hidden field form control based on the supplied name. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
name string Yes Name to populate in tag's name attribute.
value string No Value to populate in tag's value attribute.
encode boolean No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic usage with a name and value
#hiddenFieldTag(name="userId", value=user.id)#
// -> <input type="hidden" name="userId" value="42">

// 2. Embed a CSRF token in a standalone form
#hiddenFieldTag(name="csrfToken", value=session.csrfToken)#
// -> <input type="hidden" name="csrfToken" value="a1b2c3d4...">

// 3. Pass extra HTML attributes via additional arguments
#hiddenFieldTag(name="returnTo", value="/dashboard", id="returnToField")#
// -> <input type="hidden" name="returnTo" value="/dashboard" id="returnToField">

highlight()

View Helpers Miscellaneous Functions string controller

Highlights the phrase(s) everywhere in the text if found by wrapping them in span tags.

Name Type Required Default Description
text string Yes Text to search in.
phrase string No Phrase (or list of phrases) to highlight. This argument is also aliased as phrases.
delimiter string No , Delimiter to use when passing in multiple phrases.
tag string No span HTML tag to use to wrap the highlighted phrase(s).
class string No highlight Class to use in the tags wrapping highlighted phrase(s).
encode boolean No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Highlight a single phrase in text
// Outputs: You searched for: <span class="highlight">CFWheels</span> framework
result = highlight(text="You searched for: CFWheels framework", phrase="CFWheels");

// 2. Highlight multiple phrases using a comma-delimited list
// Outputs: <span class="highlight">Open</span> source <span class="highlight">CFML</span> framework
result = highlight(text="Open source CFML framework", phrase="Open,CFML");

// 3. Highlight with a custom tag and CSS class
// Outputs: Learn <strong class="match">ColdFusion</strong> today
result = highlight(text="Learn ColdFusion today", phrase="ColdFusion", tag="strong", class="match");

hourSelectTag()

View Helpers Form Tag Functions string controller

Builds and returns a string containing one select form control for the hours of the day based on the supplied name.

Name Type Required Default Description
name string Yes Name to populate in tag's name attribute.
selected string No The hour that should be selected initially.
includeBlank any No false Whether to include a blank option in the select form control. Pass true to include a blank line or a string that should represent what display text should appear for the empty value (for example, "- Select One -").
label string No The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
twelveHour boolean No false whether to display the hours in 24 or 12 hour format. 12 hour format has AM/PM drop downs
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic usage — render a select control for hours of the day
#hourSelectTag(name="hourOfMeeting", selected=params.hourOfMeeting)#

// 2. Show hours in 12-hour (AM/PM) format instead of 24-hour format
#hourSelectTag(name="hourOfMeeting", selected=params.hourOfMeeting, twelveHour=true)#

// 3. Include a blank option as a placeholder prompt and add a label
#hourSelectTag(name="startHour", selected=params.startHour, includeBlank="-- Select Hour --", label="Start Hour")#

humanize()

Global Helpers String Functions string controller model mapper migrator migration tabledefinition

Returns readable text by capitalizing and converting camel casing to multiple words.

Name Type Required Default Description
text string Yes Text to humanize.
except string No A list of strings (space separated) to replace within the output.
// 1. Humanize a camelCase string
result = humanize("wheelsIsAFramework");
// result -> "Wheels Is A Framework"

// 2. Humanize a string and replace an abbreviation using the except argument
result = humanize("wheelsIsACfmlFramework", "CFML");
// result -> "Wheels Is A CFML Framework"

// 3. Humanize a multi-word property name from a model attribute
result = humanize("firstName");
// result -> "First Name"

hyphenize()

Global Helpers String Functions string controller model mapper migrator migration tabledefinition

Converts camelCase strings to lowercase strings with hyphens as word delimiters instead. Example: myVariable becomes my-variable.

Name Type Required Default Description
string string Yes The string to hyphenize.
// 1. Basic camelCase to hyphenated string
result = hyphenize("myBlogPost");
// result -> "my-blog-post"

// 2. Single word (no change)
result = hyphenize("hello");
// result -> "hello"

// 3. Used in URL slug generation
slug = hyphenize("userProfileSettings");
// slug -> "user-profile-settings"

ignoredColumns()

Model Configuration Miscellaneous Functions void model

Use this method to specify which columns cannot be used by the wheels ORM.

Name Type Required Default Description
columns array No [runtime expression] Array of columns names that will be ignored.
// 1. Ignore a single column in the model's config() method
// In app/models/User.cfc
component extends="Model" {
	function config() {
		ignoredColumns(columns=["legacyField"]);
	}
}

// 2. Ignore multiple columns so they are excluded from Wheels ORM property mapping
// In app/models/Product.cfc
component extends="Model" {
	function config() {
		ignoredColumns(columns=["internalCode", "deprecatedFlag", "tempCache"]);
	}
}

imageTag()

View Helpers Asset Functions string controller

Returns an img tag. If the image is stored in the local images folder, the tag will also set the width, height, and alt attributes for you. You can pass any additional arguments (e.g. class, rel, id), and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
source string Yes The file name of the image if it's available in the local file system (i.e. ColdFusion will be able to access it). Provide the full URL if the image is on a remote server.
onlyPath boolean No true
host string No
protocol string No
port numeric No 0
encode boolean No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
required boolean No true
// 1. Output an img tag for a local image (width, height, and alt are auto-detected)
writeOutput(imageTag("logo.png"));

// 2. Output an img tag for an image hosted on an external server
writeOutput(imageTag(source="https://example.com/images/logo.png", alt="Company Logo"));

// 3. Output an img tag with additional HTML attributes
writeOutput(imageTag(source="logo.png", class="logo", id="mainLogo"));

// 4. Output an img tag without requiring the file to exist locally (useful in development)
writeOutput(imageTag(source="placeholder.png", required=false));

imageUrl()

string controller

URL publique d'un visuel a partir de sa cle logique. La base est configurable pour que le stockage puisse changer sans toucher aux vues : aujourd'hui un volume servi par Nginx, demain un stockage objet. C'est la raison pour laquelle la base ne stocke qu'une cle, jamais une URL.

Name Type Required Default Description
key string No

includeContent()

View Helpers Miscellaneous Functions string controller

Used to output the content for a particular section in a layout.

Name Type Required Default Description
name string No body Name of layout section to return content for.
defaultValue string No What to display as a default if the section is not defined.
// 1. Output the main page body inside a layout (default section is "body")
// In `app/views/layout.cfm`:
<html>
	<head>
		<title>My Site</title>
	</head>
	<body>
		<cfoutput>
			#includeContent()#
		</cfoutput>
	</body>
</html>

// 2. Define a named section in a view, then render it in the layout
// In `app/views/blog/show.cfm`:
contentFor(head='<meta name="description" content="Read our latest post">');

// In `app/views/layout.cfm`:
<html>
	<head>
		<title>My Site</title>
		<cfoutput>#includeContent("head")#</cfoutput>
	</head>
	<body>
		<cfoutput>#includeContent()#</cfoutput>
	</body>
</html>

// 3. Provide a default value when a section may not have been defined
<cfoutput>
	#includeContent(name="sidebar", defaultValue="<p>No sidebar content.</p>")#
</cfoutput>

includedInObject()

View Helpers Form Association Functions boolean controller

Used as a shortcut to check if the specified IDs are a part of the main form object. This method should only be used for hasMany associations.

Name Type Required Default Description
objectName string Yes Name of the variable containing the parent object to represent with this form field.
association string Yes Name of the association set in the parent object to represent with this form field.
keys string Yes Primary keys associated with this form field. Note that these keys should be listed in the order that they appear in the database table.
// 1. Check whether a customer is already subscribed to a particular publication via a hasMany join
// (Note: keys should be listed in the order they appear in the join table columns)
if (includedInObject(objectName="customer", association="subscriptions", keys="#customer.key()#,#swimsuitEdition.id#")) {
    writeOutput("Already subscribed.");
} else {
    writeOutput("Not yet subscribed.");
}

// 2. Use the return value to find the position of the associated object in the array
position = includedInObject(objectName="order", association="lineItems", keys="#lineItem.key()#");
// Returns false when not found, or the 1-based index position when found
// position -> 3 (the associated lineItem is at index 3 in order.lineItems)

// 3. Guard against adding duplicate associations before creating a new join record
if (!includedInObject(objectName="student", association="courses", keys="#course.key()#")) {
    student.courses = ArrayAppend(student.courses, course);
}

includeLayout()

View Helpers Miscellaneous Functions string controller

Includes the contents of another layout file. This is usually used to include a parent layout from within a child layout.

Name Type Required Default Description
name string No layout Name of the layout file to include.
// 1. Include the default parent layout from within a child layout
// (looks for `app/views/layout.cfm` by default)
#includeLayout()#

// 2. Include a specific parent layout by path
// (looks for `app/views/layouts/application.cfm`)
#includeLayout("/layouts/application.cfm")#

// 3. Pass section content to the parent layout before including it
// Capture sidebar markup to make it available in the parent layout
<cfsavecontent variable="sidebar">
  <nav>
    #includePartial("categories")#
  </nav>
</cfsavecontent>
<cfset contentFor(sidebar=sidebar)>

// Then pull in the parent layout that renders the sidebar via includeContent()
#includeLayout("/layouts/application.cfm")#

includePartial()

View Helpers Miscellaneous Functions string controller

Includes the specified partial file in the view. Similar to using cfinclude but with the ability to cache the result and use Wheels-specific file look-up. By default, Wheels will look for the file in the current controller's view folder. To include a file relative from the base views folder, you can start the path supplied to partial with a forward slash.

Name Type Required Default Description
partial any Yes The name of the partial file to be used. Prefix with a leading slash (/) if you need to build a path from the root views folder. Do not include the partial filename's underscore and file extension. If you want to have Wheels display the partial for a single model object, array of model objects, or a query, pass a variable containing that data into this argument.
group string No If passing a query result set for the partial argument, use this to specify the field to group the query by. A new query will be passed into the partial template for you to iterate over.
cache any No Number of minutes to cache the content for.
layout string No The layout to wrap the content in. Prefix with a leading slash (/) if you need to build a path from the root views folder. Pass false to not load a layout at all.
spacer string No HTML or string to place between partials when called using a query.
dataFunction any No true Name of controller function to load data from.
// 1. Include a partial from the current controller's view folder.
//    When in the "sessions" controller, Wheels looks for "app/views/sessions/_login.cfm".
#includePartial("login")#

// 2. Include a partial relative to the root views folder using a leading slash.
//    Wheels looks for "app/views/shared/_button.cfm".
#includePartial(partial="/shared/button")#

// 3. Pass a query to loop through records automatically.
//    Wheels loops through the result set and renders "app/views/posts/_post.cfm" for each row.
posts = model("Post").findAll();
#includePartial(posts)#

// 4. Override the template when rendering a query.
//    Provide the template path via partial and pass the query separately.
posts = model("Post").findAll();
#includePartial(partial="/shared/post", query=posts)#

// 5. Pass a single model object — Wheels renders the matching partial for its model type.
post = model("Post").findByKey(params.key);
#includePartial(post)#

// 6. Override the template when rendering a single model object.
post = model("Post").findByKey(params.key);
#includePartial(partial="/shared/post", object=post)#

// 7. Pass an array of model objects — Wheels iterates and renders the partial for each.
posts = model("Post").findAll(returnAs="objects");
#includePartial(posts)#

// 8. Override the template when rendering an array of model objects.
posts = model("Post").findAll(returnAs="objects");
#includePartial(partial="/shared/post", objects=posts)#

// 9. Cache the partial output for 30 minutes to reduce processing overhead.
#includePartial(partial="sidebar", cache=30)#

// 10. Group a query result set by a column before rendering.
//     Wheels splits the query into sub-queries grouped by "categoryId"
//     and passes each sub-query into "app/views/products/_product.cfm".
products = model("Product").findAll(order="categoryId");
#includePartial(partial="product", query=products, group="categoryId")#

// 11. Insert a separator string between each rendered partial in a loop.
posts = model("Post").findAll();
#includePartial(partial="post", query=posts, spacer="<hr>")#

initSSEStream()

any controller

Initialize a streaming SSE connection that bypasses the normal Wheels rendering pipeline. Returns a writer object that can be used with sendSSEEvent() and closeSSEStream(). This enables sending multiple events over a single connection. Note: This bypasses layouts and after-filters. Use for true streaming endpoints only.

inject()

void controller

Declare one or more services for injection into this controller. Call in config(). Services are resolved when the controller instance is created.

Name Type Required Default Description
name string Yes Comma-delimited list of registered service names to inject.

injectedServices()

array controller

Return the list of declared service names for this controller.

injector()

Global Helpers Miscellaneous Functions any controller model mapper migrator migration tabledefinition

Return a reference to the DI container for direct configuration.

// 1. Register a singleton service in `config/services.cfm` (one instance per app lifetime)
di = injector();
di.map("emailService").to("app.lib.EmailService").asSingleton();

// 2. Bind an interface name to a concrete implementation
di = injector();
di.bind("INotifier").to("app.lib.SlackNotifier").asSingleton();

// 3. Register a request-scoped service (one instance per HTTP request)
di = injector();
di.map("currentUser").to("app.lib.CurrentUserResolver").asRequestScoped();

// 4. Inspect or resolve at runtime
di = injector();
if (di.containsInstance("emailService")) {
    mailer = di.getInstance("emailService");
    mailer.send(to="user@example.com", subject="Welcome");
}

insertAll()

Model Class Create Functions struct model

Inserts multiple records into the database in a single batch operation. Accepts an array of structs where each struct represents a record to insert. All structs must have the same set of keys (property names). Batches in groups of 1000 to avoid database parameter limits.

Name Type Required Default Description
records array Yes Array of structs, each containing property name/value pairs to insert.
timestamps boolean No true Set to false to skip automatic createdAt/updatedAt timestamping.
transaction string No [runtime expression] Set this to commit to update the database, rollback to run all the database queries but not commit them, or none to skip transaction handling altogether.
parameterize any No true Set to true to use cfqueryparam on all columns, or pass in a list of property names to use cfqueryparam on those only.
// 1. Insert multiple user records in a single batch
newUsers = [
    {firstName: "Alice", lastName: "Smith", email: "alice@example.com"},
    {firstName: "Bob",   lastName: "Jones", email: "bob@example.com"},
    {firstName: "Carol", lastName: "White", email: "carol@example.com"}
];
result = model("User").insertAll(records=newUsers);
// result -> {insertedCount: 3}

// 2. Insert records without automatic createdAt/updatedAt timestamps
rows = [
    {username: "imported_1", score: 9800},
    {username: "imported_2", score: 7450}
];
result = model("HighScore").insertAll(records=rows, timestamps=false);
// result -> {insertedCount: 2}

// 3. Insert a large dataset wrapped in a single transaction, using selective cfqueryparam
products = [];
for (i = 1; i <= 2500; i++) {
    arrayAppend(products, {name: "Product #i#", price: RandRange(1, 999), stock: RandRange(0, 500)});
}
// Batches automatically in groups of 1000; all batches share one transaction.
result = model("Product").insertAll(
    records      = products,
    transaction  = "commit",
    parameterize = "price,stock"
);
// result -> {insertedCount: 2500}

integer()

Migrator Table Definition Functions any tabledefinition

adds integer columns to table definition

Name Type Required Default Description
columnNames string No
limit numeric No
default any No
allowNull boolean No
// 1. Add a single integer column to a new table
t = createTable(name='products');
	t.string(columnNames='name', limit=255, allowNull=false);
	t.integer(columnNames='quantity');
	t.timestamps();
t.create();

// 2. Add multiple integer columns at once with a default value
t = createTable(name='scores');
	t.integer(columnNames='wins,losses,draws', default=0, allowNull=false);
	t.string(columnNames='playerName', limit=100, allowNull=false);
	t.timestamps();
t.create();

// 3. Add an integer column with a limit when altering an existing table
t = changeTable(name='orders');
	t.integer(columnNames='itemCount', default=0, allowNull=false, limit=4);
t.change();

invokeWithTransaction()

Model Class Miscellaneous Functions any model

Runs the specified method within a single database transaction.

Name Type Required Default Description
method string Yes Model method to run.
transaction string No commit Set this to commit to update the database, rollback to run all the database queries but not commit them, or none to skip transaction handling altogether.
isolation string No read_committed Isolation level to be passed through to the cftransaction tag. See your CFML engine's documentation for more details about cftransaction's isolation attribute.
// 1. Run a custom model method inside a database transaction.
// Define the method on the model (e.g. Person.cfc):
public boolean function transferFunds(required any personFrom, required any personTo, required numeric amount) {
	if (arguments.personFrom.withdraw(arguments.amount) && arguments.personTo.deposit(arguments.amount)) {
		return true;
	} else {
		return false;
	}
}

// Then invoke it wrapped in a transaction from a controller action:
local.david = model("Person").findOneByName("David");
local.mary = model("Person").findOneByName("Mary");
local.success = model("Person").invokeWithTransaction(method="transferFunds", personFrom=local.david, personTo=local.mary, amount=100);

// 2. Run in rollback mode to test queries without committing changes.
local.success = model("Person").invokeWithTransaction(method="transferFunds", personFrom=local.david, personTo=local.mary, amount=100, transaction="rollback");

// 3. Run with a stricter isolation level (e.g. serializable) to prevent phantom reads.
local.success = model("Person").invokeWithTransaction(method="transferFunds", personFrom=local.david, personTo=local.mary, amount=100, isolation="serializable");

isAjax()

Controller Miscellaneous Functions boolean controller

Returns whether the page was called from JavaScript or not.

// 1. Respond differently based on whether the request is an AJAX call
if (isAjax()) {
    renderNothing();
} else {
    redirectTo(action = "index");
}

// 2. Return JSON for AJAX requests, render a full view otherwise
if (isAjax()) {
    renderWith(data = model("Article").findAll(returnAs = "objects"));
} else {
    articles = model("Article").findAll();
}

isClass()

Model Class Miscellaneous Functions string model

Use this method to check whether you are currently in a class-level object.

// 1. Use isClass() to branch between class-level and instance-level behavior
// In a model method, detect whether the method is being called on the class
// (e.g. model("User").isAdmin(42)) or on an instance (e.g. user.isAdmin()).
function isAdmin(numeric id) {
	if (isClass()) {
		// Called on the class — look up the record by the provided id
		return this.findByKey(arguments.id).admin;
	} else {
		// Called on an instance — the property is already available
		return this.admin;
	}
}

// 2. Guard a class-only operation
function resetAllPasswords() {
	if (!isClass()) {
		Throw(type="App.Error", message="resetAllPasswords must be called on the class, not an instance.");
	}
	this.updateAll(password="changeme");
}

isDelete()

Controller Miscellaneous Functions boolean controller

Returns whether the request was a DELETE request or not.

// 1. Only process delete logic when the request method is DELETE
if (isDelete()) {
    // perform delete operation
}

// 2. Assign the result to a variable for later use
requestIsDelete = isDelete();

isGet()

Controller Miscellaneous Functions boolean controller

Returns whether the request was a normal GET request or not.

// 1. Only allow GET requests in an action
if (!isGet()) {
    redirectTo(action = "index");
}

// 2. Respond differently depending on the HTTP method
if (isGet()) {
    // Render the form for display
    user = model("User").findByKey(params.key);
} else {
    // Handle a non-GET submission
    renderNothing();
}

// 3. Store the result to use in a conditional
requestIsGet = isGet();
// requestIsGet -> true (for a normal page request), false otherwise

isHead()

Controller Miscellaneous Functions boolean controller

Returns whether the request was a HEAD request or not.

// 1. Respond to a HEAD request by rendering nothing
if (isHead()) {
    renderNothing();
}

// 2. Restrict an action to HEAD requests only
if (!isHead()) {
    renderText("Method not allowed");
}

// 3. Store the result to use in a conditional
requestIsHead = isHead();
// requestIsHead -> true when the HTTP method is HEAD, false otherwise

isInstance()

Model Class Miscellaneous Functions boolean model

Use this method to check whether you are currently in an instance object.

// 1. Branch logic inside a shared model method based on class vs. instance context
function memberIsAdmin() {
	if (isInstance()) {
		// Called on an instance object — property is already loaded
		return this.admin;
	} else {
		// Called on the class — look up the record first
		return this.findByKey(arguments.id).admin;
	}
}

// 2. Use isInstance() in config() to guard instance-only setup
component extends="Model" {
	function config() {
		if (isInstance()) {
			// Instance-specific initialization (rarely needed; shown for contrast)
		} else {
			// Class-level configuration: validations, associations, callbacks
			validatesPresenceOf(properties="username,email");
			hasMany(name="posts");
		}
	}
}

// 3. Pair with isClass() to make the intent explicit
function label() {
	if (isClass()) {
		return "User (class)";
	}
	return "User #this.id#";
}

isNew()

Model Object Miscellaneous Functions boolean model

Returns true if this object hasn't been saved yet (in other words, no matching record exists in the database yet). Returns false if a record exists.

// 1. Check if a newly instantiated object has been saved to the database
employee = model("Employee").new(firstName="Jane", lastName="Doe");
if (employee.isNew()) {
    // employee.save() has not been called yet, so no DB record exists
    employee.save();
}

// 2. Check after loading from the database (isNew() returns false for persisted records)
employee = model("Employee").findOne(where="firstName='Jane'");
if (!employee.isNew()) {
    // record already exists in the database
    employee.firstName = "Janet";
    employee.save();
}

// 3. Useful inside a before/after callback to branch logic for new vs. existing records
// In Employee.cfc:
component extends="Model" {
    function config() {
        beforeSave("stampAuditFields");
    }
    private function stampAuditFields() {
        if (isNew()) {
            this.createdBy = request.currentUserId;
        }
        this.updatedBy = request.currentUserId;
    }
}

isOptions()

Controller Miscellaneous Functions boolean controller

Returns whether the request was an OPTIONS request or not.

// 1. Respond to a CORS preflight OPTIONS request
if (isOptions()) {
    header(name = "Access-Control-Allow-Methods", value = "GET, POST, PUT, DELETE");
    renderNothing();
    return;
}

// 2. Restrict an action to only handle OPTIONS requests
if (!isOptions()) {
    redirectTo(action = "index");
}

// 3. Store the result to use in a conditional
requestIsOptions = isOptions();
// requestIsOptions -> true when the HTTP method is OPTIONS, false otherwise

isPatch()

Controller Miscellaneous Functions boolean controller

Returns whether the request was a PATCH request or not.

// 1. Only handle PATCH requests in an action
if (!isPatch()) {
    redirectTo(action = "index");
}

// 2. Respond differently depending on whether the request is a PATCH
if (isPatch()) {
    // Apply a partial update to the resource
    user = model("User").findByKey(params.key);
    user.update(params.user);
} else {
    // Not a PATCH request; redirect away
    redirectTo(action = "index");
}

// 3. Store the result to use in a conditional
requestIsPatch = isPatch();
// requestIsPatch -> true for a PATCH request, false otherwise

isPersisted()

Model Object Miscellaneous Functions boolean model

Returns true if this object has been persisted to the database or was loaded from the database via a finder. Returns false if the record has not been persisted to the database.

// 1. Check if a newly created (unsaved) object has been persisted
user = model("User").new(firstName="Jane", lastName="Doe");
writeOutput(user.isPersisted()); // -> false

// 2. Check if an object loaded from the database is persisted
user = model("User").findByKey(1);
writeOutput(user.isPersisted()); // -> true

// 3. Check persistence after saving a new object
post = model("Post").new(title="Hello World", body="First post.");
post.save();
writeOutput(post.isPersisted()); // -> true

isPost()

Controller Miscellaneous Functions boolean controller

Returns whether the request came from a form POST submission or not.

// 1. Respond differently depending on whether the request is a POST
if (isPost()) {
    // Process the submitted form data
    user = model("User").new(params.user);
    if (user.save()) {
        redirectTo(action="index");
    } else {
        renderView(action="new");
    }
} else {
    renderView(action="new");
}

// 2. Guard an action so it only accepts POST requests
function create() {
    if (!isPost()) {
        renderNothing(status="405 Method Not Allowed");
        return;
    }
    // handle form submission
}

// 3. Store the result for later use in the action
requestIsPost = isPost();
// requestIsPost -> true (when submitted via a form POST)
// requestIsPost -> false (when the page is visited normally with GET)

isPut()

Controller Miscellaneous Functions boolean controller

Returns whether the request was a PUT request or not.

// 1. Allow only PUT requests for a resource update action
if (!isPut()) {
    redirectTo(action = "index");
}
// ... proceed with update logic

// 2. Branch behavior based on HTTP method
if (isPut()) {
    // Full replacement of the resource
    user = model("User").findByKey(params.key);
    user.update(params.user);
    redirectTo(action = "show", key = user.key());
} else {
    renderNothing();
}

isSecure()

Controller Miscellaneous Functions boolean controller

Returns whether Wheels is communicating over a secure port. X-Forwarded-Proto is client-controlled and is only honored when the app has opted into proxy trust via set(trustProxyHeaders=true) behind a trusted reverse proxy.

// 1. Redirect non-secure connections to the HTTPS version
if (!isSecure()) {
	redirectTo(protocol="https");
}

// 2. Conditionally set a secure cookie flag based on the connection
cookieOptions = {secure: isSecure(), httpOnly: true};

// 3. Log a warning when a sensitive action is performed over a non-secure connection
if (!isSecure()) {
	logMessage("WARNING: sensitive action performed over non-secure connection");
}

isSSERequest()

boolean controller

Check if the current request is from an EventSource client. Useful for conditionally rendering SSE vs HTML responses.

javaScriptIncludeTag()

View Helpers Asset Functions string controller

Returns a script tag for a JavaScript file (or several) based on the supplied arguments.

Name Type Required Default Description
sources string No The name of one or many JavaScript files in the javascripts folder, minus the .js extension. Pass a full URL to access an external JavaScript file. Can also be called with the source argument.
type string No text/javascript The type attribute for the script tag.
head boolean No false Set to true to place the output in the head area of the HTML page instead of the default behavior (which is to place the output where the function is called from).
delim string No , The delimiter to use for the list of JavaScript files.
encode boolean No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
<!--- view code --->
<head>
    <!--- Includes `javascripts/main.js` --->
    #javaScriptIncludeTag("main")#

    <!--- Includes `javascripts/blog.js` and `javascripts/accordion.js` --->
    #javaScriptIncludeTag("blog,accordion")#

    <!--- Includes an external JavaScript file --->
    #javaScriptIncludeTag("https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js")#

    <!--- Uses a pipe delimiter instead of the default comma --->
    #javaScriptIncludeTag(sources="app|utils|vendor", delim="|")#
</head>

<body>
    <!--- Will still appear in the `head` --->
    #javaScriptIncludeTag(source="tabs", head=true)#
</body>

key()

Model Object Miscellaneous Functions string model

Returns the value of the primary key for the object. If you have a single primary key named id, then someObject.key() is functionally equivalent to someObject.id. This method is more useful when you do dynamic programming and don't know the name of the primary key or when you use composite keys (in which case it's convenient to use this method to get a list of both key values returned).

Name Type Required Default Description
// 1. Get the primary key value of a found object
employee = model("Employee").findByKey(params.key);
writeOutput(employee.key());
// -> 42

// 2. Use key() when you don't know the primary key column name (dynamic programming)
obj = model(params.modelName).findByKey(params.id);
if (IsObject(obj)) {
	writeOutput("Found record with key: " & obj.key());
}

// 3. Composite primary key — key() returns a comma-delimited list of both values
orderItem = model("OrderItem").findByKey(key="1,5");
writeOutput(orderItem.key());
// -> 1,5 (orderId and productId combined)

linkTo()

View Helpers Link Functions string controller

Creates a link to another page in your application. Pass in the name of a route to use your configured routes or a controller/action/key combination. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
text string No The text content of the link.
route string No Name of a route that you have configured in config/routes.cfm.
controller string No Name of the controller to include in the URL.
action string No Name of the action to include in the URL.
key any No Key(s) to include in the URL.
params string No Any additional parameters to be set in the query string (example: wheels=cool&x=y). Please note that Wheels uses the & and = characters to split the parameters and encode them properly for you. However, if you need to pass in & or = as part of the value, then you need to encode them (and only them), example: a=cats%26dogs%3Dtrouble!&b=1.
anchor string No Sets an anchor name to be appended to the path.
onlyPath boolean No true If true, returns only the relative URL (no protocol, host name or port).
host string No Set this to override the current host.
protocol string No Set this to override the current protocol.
port numeric No 0 Set this to override the current port number.
href string No Pass a link to an external site here if you want to bypass the Wheels routing system altogether and link to an external URL.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Link to a controller/action pair
writeOutput(linkTo(text="Log Out", controller="account", action="logout"));
// -> <a href="/account/logout">Log Out</a>

// 2. Omit the controller when linking within the same controller
// (CFWheels uses the current controller automatically)
writeOutput(linkTo(text="Log Out", action="logout"));
// -> <a href="/account/logout">Log Out</a>

// 3. Link to a specific record using a key
writeOutput(linkTo(text="View Post", controller="blog", action="post", key=99));
// -> <a href="/blog/post/99">View Post</a>

// 4. Pass extra query string parameters
writeOutput(linkTo(text="View Settings", action="settings", params="show=all&sort=asc"));
// -> <a href="/account/settings?show=all&amp;sort=asc">View Settings</a>

// 5. Use a named route (configured in app/config/routes.cfm)
writeOutput(linkTo(text="Joe's Profile", route="userProfile", userName="joe"));
// -> <a href="/user/joe">Joe's Profile</a>

// 6. Link to an external URL, bypassing the routing system
writeOutput(linkTo(text="ColdFusion on Wheels", href="https://cfwheels.org/"));
// -> <a href="https://cfwheels.org/">ColdFusion on Wheels</a>

// 7. Add HTML attributes (class, id, rel, etc.) via extra arguments
writeOutput(linkTo(text="Delete Post", action="delete", key=99, class="delete", id="delete-99"));
// -> <a class="delete" href="/blog/delete/99" id="delete-99">Delete Post</a>

// 8. Include icon markup in link text; use encode="attributes" to encode
//    only attribute values and leave the tag content (the icon HTML) untouched
writeOutput(linkTo(text="<i class='fa fa-trash'></i> Delete Post", encode="attributes", action="delete", key=99));
// -> <a href="/blog/delete/99"><i class='fa fa-trash'></i> Delete Post</a>

// 9. Build an absolute URL by turning off onlyPath and setting a protocol/host
writeOutput(linkTo(text="Home", action="index", onlyPath=false, protocol="https", host="www.example.com"));
// -> <a href="https://www.example.com/home/index">Home</a>

// 10. Link to an anchor on the target page
writeOutput(linkTo(text="Jump to Comments", controller="blog", action="post", key=99, anchor="comments"));
// -> <a href="/blog/post/99#comments">Jump to Comments</a>

mailTo()

View Helpers Link Functions string controller

Creates a mailto link tag to the specified email address, which is also used as the name of the link unless name is specified.

Name Type Required Default Description
emailAddress string Yes The email address to link to.
name string No A string to use as the link text ("Joe" or "Support Department", for example).
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic mailto link using the email address as the link text
mailTo(emailAddress="webmaster@example.com");
// -> <a href="mailto:webmaster@example.com">webmaster@example.com</a>

// 2. Mailto link with a custom display name
mailTo(emailAddress="support@example.com", name="Contact Support");
// -> <a href="mailto:support@example.com">Contact Support</a>

// 3. Mailto link with additional HTML attributes (class, title)
mailTo(emailAddress="info@example.com", name="Email Us", class="email-link", title="Send us a message");
// -> <a href="mailto:info@example.com" class="email-link" title="Send us a message">Email Us</a>

mapper()

Configuration Routing struct controller model mapper migrator migration tabledefinition

Returns the mapper object used to configure your application's routes. Usually you will use this method in config/routes.cfm to start chaining route mapping methods like resources, namespace, etc.

Name Type Required Default Description
restful boolean No true Whether to turn on RESTful routing or not. Not recommended to set. Will probably be removed in a future version of wheels, as RESTful routes are the default.
methods boolean No [runtime expression] If not RESTful, then specify allowed routes. Not recommended to set. Will probably be removed in a future version of wheels, as RESTful routes are the default.
mapFormat boolean No true This is useful for providing formats via URL like json, xml, pdf, etc. Set to false to disable automatic .[format] generation for resource based routes

maximum()

Model Class Statistics Functions any model

Calculates the maximum value for a given property. Uses the SQL function MAX. If no records can be found to perform the calculation on you can use the ifNull argument to decide what should be returned.

Name Type Required Default Description
property string Yes Name of the property to get the highest value for (must be a property of a numeric data type).
where string No Maps to the WHERE clause of the query (or HAVING when necessary). The following operators are supported: =, !=, <>, <, <=, >, >=, LIKE, NOT LIKE, IN, NOT IN, IS NULL, IS NOT NULL, AND, and OR (note that the key words need to be written in upper case). You can also use parentheses to group statements. Nested queries not allowed. You do not need to specify the table name(s); Wheels will do that for you.
include string No Associations that should be included in the query using INNER or LEFT OUTER joins (which join type that is used depends on how the association has been set up in your model). If all included associations are set on the current model, you can specify them in a list (e.g. department,addresses,emails). You can build more complex include strings by using parentheses when the association is set on an included model, like album(artist(genre)), for example. These complex include strings only work when returnAs is set to query though.
parameterize any No true
ifNull any No The value returned if no records are found. Common usage is to set this to 0 to make sure a numeric value is always returned instead of a blank string.
includeSoftDeletes boolean No false Set to true to include soft-deleted records in the queries that this method runs.
group string No Maps to the GROUP BY clause of the query. You do not need to specify the table name(s); Wheels will do that for you.
// 1. Get the highest salary across all employees
highestSalary = model("employee").maximum("salary");

// 2. Get the highest salary for employees in a specific department
highestSalary = model("employee").maximum(property="salary", where="departmentId=#params.key#");

// 3. Return 0 instead of a blank string when no matching records are found
highestSalary = model("employee").maximum(property="salary", where="salary > #params.minSalary#", ifNull=0);

// 4. Get the highest salary per department (returns a query with departmentId and the maximum value)
salaryByDept = model("employee").maximum(property="salary", group="departmentId");

member()

Configuration Routing struct mapper

Scope routes within a nested resource which require use of the primary key as part of the URL pattern; A member route will require an ID, because it acts on a member. photos/1/preview is an example of a member route, because it acts on (and displays) a single object.

<cfscript>

// 1. Add a preview route acting on a single photo (GET /photos/1/preview)
mapper()
    .resources(name="photos", nested=true)
        .member()
            .get("preview")
        .end()
    .end()
.end();

// 2. Add multiple member routes (GET /articles/1/publish, DELETE /articles/1/archive)
mapper()
    .resources(name="articles", nested=true)
        .member()
            .get("publish")
            .delete("archive")
        .end()
    .end()
.end();

</cfscript>

migrateIndividual()

Migrator General Functions string migrator

Runs a single specific migration's up() regardless of sequence order. Used for out-of-sequence migrations that were created by other developers and need to be applied individually without affecting the current version pointer.

Name Type Required Default Description
version string Yes The version number of the specific migration to run
// 1. Run a specific migration by version number (out-of-sequence)
result = application.wheels.migrator.migrateIndividual("20240315120000");
// result -> "Running individual migration 20240315120000.
// -------- 20240315120000_add_status_to_orders --------------------
// "

// 2. Check the result string for errors or success messages
result = application.wheels.migrator.migrateIndividual("20240101000000");
if (FindNoCase("Error", result)) {
    writeOutput("Migration failed: " & result);
} else if (FindNoCase("already been applied", result)) {
    writeOutput("Skipped: migration was already applied.");
} else {
    writeOutput("Migration applied successfully.");
}

// 3. Apply an individual colleague's migration without advancing the version pointer
// This is useful when a team member's migration has a lower timestamp than
// the current version but was not yet applied in your environment.
colVersion = "20231205083000";
result = application.wheels.migrator.migrateIndividual(colVersion);
writeOutput(result);

migrateTo()

Migrator General Functions string migrator

Migrates database to a specified version. Whilst you can use this in your application, the recommended usage is via either the CLI or the provided GUI interface

Name Type Required Default Description
version string No The Database schema version to migrate to
missingMigFlag boolean No false Flag for any available missing migrations
// 1. Migrate up to a specific version
result = application.wheels.migrator.migrateTo("20240315120000");
// result -> "Migrating from 20231201000000 up to 20240315120000.
// -------- 20240315120000_add_status_to_orders --------------------
// "

// 2. Migrate down to an earlier version (rolls back newer migrations)
result = application.wheels.migrator.migrateTo("20230601000000");
// result -> "Migrating from 20240315120000 down to 20230601000000.
// ------- 20240315120000_add_status_to_orders ---------------------
// "

// 3. Migrate to version 0 (rolls back all migrations)
result = application.wheels.migrator.migrateTo("0");
// result -> "Migrating from 20240315120000 down to 0.
// ..."

// 4. Check the result string for errors before proceeding
result = application.wheels.migrator.migrateTo("20240315120000");
if (FindNoCase("Error", result)) {
    writeOutput("Migration failed: " & result);
} else {
    writeOutput("Migration result: " & result);
}

// 5. Apply a missing (out-of-order gap) migration using missingMigFlag
// Use this when a migration with a timestamp earlier than the current version
// was never applied in your environment.
result = application.wheels.migrator.migrateTo(
    version = "20231205083000",
    missingMigFlag = true
);
writeOutput(result);

migrateToLatest()

Migrator General Functions string migrator

Shortcut function to migrate to the latest version

// 1. Run all pending migrations to bring the database up to the latest version
result = application.wheels.migrator.migrateToLatest();
// result -> "Migrating from 20240101000000 up to 20240315120000.
// -------- 20240315120000_add_status_to_orders --------------------
// "

// 2. Already at the latest version — no migration required
result = application.wheels.migrator.migrateToLatest();
// result -> "Database is currently at version 20240315120000. No migration required."

// 3. Check for errors after migrating to latest
result = application.wheels.migrator.migrateToLatest();
if (FindNoCase("Error", result)) {
    writeOutput("Migration failed: " & result);
} else {
    writeOutput("All migrations applied successfully.");
}

mimeTypes()

Global Helpers Miscellaneous Functions string controller model mapper migrator migration tabledefinition

Returns an associated MIME type based on a file extension.

Name Type Required Default Description
extension string Yes The extension to get the MIME type for.
fallback string No application/octet-stream The fallback MIME type to return.
// 1. Get the MIME type for a known file extension
mimeType = mimeTypes("xls");
// mimeType -> "application/vnd.ms-excel"

// 2. Get the MIME type for a dynamic extension from user input, with a custom fallback
mimeType = mimeTypes(extension=params.fileType, fallback="text/plain");

// 3. Use the default fallback (application/octet-stream) for an unknown extension
mimeType = mimeTypes("xyz");
// mimeType -> "application/octet-stream"

minimum()

Model Class Statistics Functions any model

Calculates the minimum value for a given property. Uses the SQL function MIN. If no records can be found to perform the calculation on you can use the ifNull argument to decide what should be returned.

Name Type Required Default Description
property string Yes Name of the property to get the lowest value for (must be a property of a numeric data type).
where string No Maps to the WHERE clause of the query (or HAVING when necessary). The following operators are supported: =, !=, <>, <, <=, >, >=, LIKE, NOT LIKE, IN, NOT IN, IS NULL, IS NOT NULL, AND, and OR (note that the key words need to be written in upper case). You can also use parentheses to group statements. Nested queries not allowed. You do not need to specify the table name(s); Wheels will do that for you.
include string No Associations that should be included in the query using INNER or LEFT OUTER joins (which join type that is used depends on how the association has been set up in your model). If all included associations are set on the current model, you can specify them in a list (e.g. department,addresses,emails). You can build more complex include strings by using parentheses when the association is set on an included model, like album(artist(genre)), for example. These complex include strings only work when returnAs is set to query though.
parameterize any No true Set to true to use cfqueryparam on all columns, or pass in a list of property names to use cfqueryparam on those only.
ifNull any No The value returned if no records are found. Common usage is to set this to 0 to make sure a numeric value is always returned instead of a blank string.
includeSoftDeletes boolean No false Set to true to include soft-deleted records in the queries that this method runs.
group string No Maps to the GROUP BY clause of the query. You do not need to specify the table name(s); Wheels will do that for you.
// 1. Get the amount of the lowest salary for all employees
lowestSalary = model("employee").minimum("salary");

// 2. Get the amount of the lowest salary for employees in a given department
lowestSalary = model("employee").minimum(property="salary", where="departmentId=#params.key#");

// 3. Make sure a numeric amount is always returned, even when there were no records analyzed by the query
lowestSalary = model("employee").minimum(property="salary", where="salary BETWEEN #params.min# AND #params.max#", ifNull=0);

minuteSelectTag()

View Helpers Form Tag Functions string controller

Builds and returns a string containing one select form control for the minutes of an hour based on the supplied name.

Name Type Required Default Description
name string Yes Name to populate in tag's name attribute.
selected string No The minute that should be selected initially.
minuteStep numeric No 1 Pass in 10 to only show minute 10, 20, 30, etc.
includeBlank any No false Whether to include a blank option in the select form control. Pass true to include a blank line or a string that should represent what display text should appear for the empty value (for example, "- Select One -").
label string No The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic usage — the "Tag" version accepts a `name` and `selected` instead of binding to a model object
<cfoutput>
    #minuteSelectTag(name="minuteOfMeeting", selected=params.minuteOfMeeting)#
</cfoutput>

// 2. Only show 15-minute intervals
<cfoutput>
    #minuteSelectTag(name="minuteOfMeeting", selected=params.minuteOfMeeting, minuteStep=15)#
</cfoutput>

// 3. Include a blank option and add a label
<cfoutput>
    #minuteSelectTag(name="minuteOfMeeting", selected=params.minuteOfMeeting, includeBlank=true, label="Minute")#
</cfoutput>

model()

Global Helpers Miscellaneous Functions any controller model mapper migrator migration tabledefinition

Returns a reference to the requested model so that class level methods can be called on it.

Name Type Required Default Description
name string Yes Name of the model to get a reference to.
// 1. Get a reference to the User model and call a class-level finder on it
user = model("User").findByKey(params.key);

// 2. Find all active users by calling findAll() on the model reference
activeUsers = model("User").findAll(where="active = 1", order="lastName");

// 3. Create a new record via the model reference
newPost = model("Post").new(title=params.title, body=params.body);
newPost.save();

// 4. Count records using the model reference
totalOrders = model("Order").count(where="status = 'pending'");

monthSelectTag()

View Helpers Form Tag Functions string controller

Builds and returns a string containing a select form control for the months of the year based on the supplied name.

Name Type Required Default Description
name string Yes Name to populate in tag's name attribute.
selected string No The month that should be selected initially.
monthDisplay string No names Pass in names, numbers, or abbreviations to control display.
monthNames string No January,February,March,April,May,June,July,August,September,October,November,December [see:dateSelect].
monthAbbreviations string No Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec [see:dateSelect].
includeBlank any No false Whether to include a blank option in the select form control. Pass true to include a blank line or a string that should represent what display text should appear for the empty value (for example, "- Select One -").
label string No The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic usage: render a month select tag bound to a form param
<cfoutput>
    #monthSelectTag(name="monthOfBirthday", selected=params.monthOfBirthday)#
</cfoutput>

// 2. Display month abbreviations instead of full names and include a blank prompt
<cfoutput>
    #monthSelectTag(
        name="month",
        selected=params.month,
        monthDisplay="abbreviations",
        includeBlank="- Select Month -"
    )#
</cfoutput>

// 3. Display month numbers with a label wrapped around the control
<cfoutput>
    #monthSelectTag(
        name="expirationMonth",
        selected=params.expirationMonth,
        monthDisplay="numbers",
        label="Expiration Month"
    )#
</cfoutput>

namespace()

Configuration Routing struct mapper

Scopes any the controllers for any routes configured within this block to a subfolder (package) and also adds the package name to the URL.

Name Type Required Default Description
name string Yes Name to prepend to child route names.
package string No [runtime expression] Subfolder (package) to reference for controllers. This defaults to the value provided for name.
path string No [runtime expression] Subfolder path to add to the URL.
<cfscript>

mapper()
    .namespace("api")
        .namespace("v2")
            // Route name:  apiV2Products
            // Example URL: /api/v2/products/1234
            // Controller:  api.v2.Products
            .resources("products")
        .end()

        .namespace("v1")
            // Route name:  apiV1Users
            // Example URL: /api/v1/users
            // Controller:  api.v1.Users
            .get(name="users", to="users##index")
        .end()
    .end()

    // Custom package and path: name="foo", package="foos", path="foose"
    // The `path` argument overrides the default URL prefix (which would be "foo").
    // The `package` argument overrides the default controller subfolder (which would be "foo").
    .namespace(name="foo", package="foos", path="foose")
        // Route name:  fooBars
        // Example URL: /foose/bars
        // Controller:  foos.Bars
        .post(name="bars", to="bars##create")
    .end()
.end();

</cfscript>

nestedProperties()

Model Configuration Miscellaneous Functions void model

Allows for nested objects, structs, and arrays to be set from params and other generated data.

Name Type Required Default Description
association string No The association (or list of associations) you want to allow to be set through the params. This argument is also aliased as associations.
autoSave boolean No true Whether to save the association(s) when the parent object is saved.
allowDelete boolean No false Set this to true to tell Wheels to look for the property _delete in your model. If present and set to a value that evaluates to true, the model will be deleted when saving the parent.
sortProperty string No Set this to a property on the object that you would like to sort by. The property should be numeric, should start with 1, and should be consecutive. Only valid with hasMany associations.
rejectIfBlank string No A list of properties that should not be blank. If any of the properties are blank, any CRUD operations will be rejected.
// 1. In `models/User.cfc`, allow `groupEntitlements` to be saved and deleted through the `user` object.
function config() {
	hasMany("groupEntitlements");
	nestedProperties(association="groupEntitlements", allowDelete=true);
}

// 2. Allow nested `addresses` to be saved but not auto-saved with the parent; also reject blank `street` values.
function config() {
	hasMany("addresses");
	nestedProperties(association="addresses", autoSave=false, rejectIfBlank="street");
}

// 3. Allow nested `lineItems` with a sort order driven by the `position` property, and enable deletion.
function config() {
	hasMany("lineItems");
	nestedProperties(association="lineItems", allowDelete=true, sortProperty="position");
}

// 4. Enable nested properties for multiple associations at once.
function config() {
	hasOne("profile");
	hasMany("phoneNumbers");
	nestedProperties(associations="profile,phoneNumbers");
}

new()

Model Class Create Functions any model

Creates a new object based on supplied properties and returns it. The object is not saved to the database, it only exists in memory. Property names and values can be passed in either using named arguments or as a struct to the properties argument.

Name Type Required Default Description
properties struct No [runtime expression] The properties you want to set on the object (can also be passed in as named arguments).
callbacks boolean No true Set to false to disable callbacks for this method.
allowExplicitTimestamps boolean No false Set this to true to allow explicit assignment of createdAt or updatedAt properties
// 1. Create a new author in memory (not saved to the database)
newAuthor = model("author").new();

// 2. Create a new author by passing in a struct of properties
newAuthor = model("author").new(params.authorStruct);

// 3. Create a new author by passing in named arguments
newAuthor = model("author").new(firstName="John", lastName="Doe");

// 4. Create a new object without running callbacks
newAuthor = model("author").new(firstName="Jane", callbacks=false);

// 5. Create a new object and allow explicit assignment of timestamp properties
newAuthor = model("author").new(firstName="Bob", createdAt="2024-01-01", allowExplicitTimestamps=true);

// 6. Scoped call via a `hasMany` association (calls `model("order").new(customerId=aCustomer.id)` internally)
aCustomer = model("customer").findByKey(params.customerId);
anOrder = aCustomer.newOrder(shipping=params.shipping);

numberField()

View Helpers Form Object Functions string controller

Builds and returns a string containing a number field form control based on the supplied objectName and property. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
objectName any Yes The variable name of the object to build the form control for.
property string Yes The name of the property to use in the form control.
association string No The name of the association that the property is located on. Used for building nested forms that work with nested properties. If you are building a form with deep nesting, simply pass in a list to the nested object, and Wheels will figure it out.
position string No The position used when referencing a hasMany relationship in the association argument. Used for building nested forms that work with nested properties. If you are building a form with deep nestings, simply pass in a list of positions, and Wheels will figure it out.
min string No Minimum allowed value.
max string No Maximum allowed value.
step string No Stepping interval.
label string No useDefaultLabel The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
errorElement string No span HTML tag to wrap the form control with when the object contains errors.
errorClass string No field-with-errors The class name of the HTML tag that wraps the form control when there are errors.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic number field bound to a model object
#numberField(objectName="product", property="price")#

// 2. Number field with a label and min/max/step constraints
#numberField(label="Quantity", objectName="orderItem", property="quantity", min="1", max="100", step="1")#

// 3. Number field for a nested association (line items in an order)
<cfloop from="1" to="#ArrayLen(order.lineItems)#" index="i">
	#numberField(label="Amount ##i#", objectName="order", association="lineItems", position=i, property="amount", min="0")#
</cfloop>

numberFieldTag()

View Helpers Form Tag Functions string controller

Builds and returns a string containing a number field form control based on the supplied name. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
name string Yes Name to populate in tag's name attribute.
value string No Value to populate in tag's value attribute.
min string No Minimum allowed value.
max string No Maximum allowed value.
step string No Stepping interval.
label string No The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic number field with a name and current value
#numberFieldTag(name="quantity", value=params.quantity)#

// 2. Number field with min, max, and step constraints plus a label
#numberFieldTag(name="rating", value=params.rating, label="Rating", min="1", max="5", step="1")#

// 3. Number field with a CSS class and prepended label text
#numberFieldTag(name="price", value=params.price, label="Price ($)", min="0", step="0.01", class="price-input")#

obfuscateParam()

Global Helpers Miscellaneous Functions string controller model mapper migrator migration tabledefinition

Obfuscates a value. Typically used for hiding primary key values when passed along in the URL.

Name Type Required Default Description
param any Yes The value to obfuscate.
// 1. Obfuscate a primary key value before including it in a URL
obfuscatedId = obfuscateParam(99);
// obfuscatedId -> "a3f6c1" (an obfuscated hex string)

// 2. Use an obfuscated key in a generated URL to hide the real record ID
params.userKey = obfuscateParam(model("User").findOne().key());
redirectTo(route="userProfile", key=params.userKey);

// 3. Reverse the obfuscation with deobfuscateParam to get the original value back
obfuscated = obfuscateParam(42);
original = deobfuscateParam(obfuscated);
// original -> "42"

offerPrice()

string controller

Prix d'une offre, recompose depuis ses trois colonnes.

Name Type Required Default Description
price any No [runtime expression]

onlyProvides()

Controller Provides Functions void controller

Use this in an individual controller action to define which formats the action will respond with. This can be used to define provides behavior in individual actions or to override a global setting set with provides in the controller's config(). Restrictions are enforced (since 4.0.4): renderWith() falls back to the html view for a format outside the list, and the automatic render in $callAction() skips view rendering for non-acceptable, non-html formats.

Name Type Required Default Description
formats string No Formats to instruct the controller to provide. Valid values are html (the default), xml, json, csv, pdf, and xls.
action string No [runtime expression] Name of action, defaults to current.
// 1. Override a global `provides()` setting for a single action — only respond with HTML
onlyProvides("html");

// 2. Allow a specific action to respond with JSON and XML only
onlyProvides("json,xml");

// 3. Override the provides formats for a named action from within another context (e.g. config())
onlyProvides(formats="json", action="create");

onMissingMethod()

Model Class Miscellaneous Functions any model

This method is not designed to be called directly from your code, but provides functionality for dynamic finders such as findOneByEmail()

Name Type Required Default Description
missingMethodName string Yes
missingMethodArguments struct Yes
// Note: onMissingMethod() is not called directly. It is the CFML hook that
// powers Wheels' dynamic model methods. The examples below show what you
// call in your code — Wheels intercepts each one automatically.

// 1. Dynamic finder: findOneBy<Property>
// Finds the first user whose email matches the given value.
user = model("User").findOneByEmail("jane@example.com");

// 2. Dynamic finder: findAllBy<Property>
// Finds all posts with the given status.
posts = model("Post").findAllByStatus("published");

// 3. Dynamic finder across multiple properties joined by "And"
// Finds a single order matching both customerId and status.
order = model("Order").findOneByCustomerIdAndStatus(42, "pending");

// 4. Find or create by property
// Returns an existing tag with the name "cfml", or creates one if none exists.
tag = model("Tag").findOrCreateByName("cfml");

// 5. Association helpers generated for hasMany (comments on a post)
post = model("Post").findByKey(1);
// Retrieve all associated comments
comments = post.comments();
// Count associated comments
total = post.commentCount();
// Create a new associated comment (foreign key set automatically)
post.createComment(body="Great post!");

// 6. Property change helpers
user = model("User").findByKey(1);
user.email = "new@example.com";
// Check whether a specific property has changed since the record was loaded
changed = user.emailHasChanged();
// Get the original value before the change
original = user.emailChangedFrom();

// 7. Enum boolean helpers (requires enum() declaration in model config)
// component Post extends="Model" { function config() { enum(property="status", values="draft,published,archived"); } }
post = model("Post").findByKey(1);
writeOutput(post.isPublished()); // true or false
writeOutput(post.isDraft());     // true or false

package()

Configuration Routing struct mapper

Scopes any the controllers for any routes configured within this block to a subfolder (package) without adding the package name to the URL.

Name Type Required Default Description
name string Yes Name to prepend to child route names.
package string No [runtime expression] Subfolder (package) to reference for controllers. This defaults to the value provided for name.
<cfscript>

// 1. Scope controllers into a subfolder without adding the package name to the URL
mapper()
    .package("admin")
        // Route name:  adminProducts
        // Example URL: /products (no "admin" in the URL)
        // Controller:  admin.Products
        .resources("products")

        // Example URL: /users (no "admin" in the URL)
        // Controller:  admin.Users
        .resources("users")
    .end()
.end();

// 2. Use the `package` argument to override the subfolder name
mapper()
    .package(name="v2", package="api/v2")
        // Route name:  v2Articles
        // Example URL: /articles
        // Controller:  api/v2.Articles
        .resources("articles")
    .end()
.end();

// 3. Nest a `package` inside a resource to scope sub-resource controllers
mapper()
    .resources(name="users", nested=true)
        // Calling `package` here scopes nested routes to a subfolder without
        // changing the URL structure.
        .package("users")
            // Route name:  usersProfile
            // Example URL: /users/4321/profile
            // Controller:  users.Profiles
            .resource("profile")
        .end()
    .end()
.end();

</cfscript>

pageDescription()

string controller

pageTitle()

string controller

Titre de la page, defini par le controleur via request.pageTitle. Le suffixe est ajoute ici et non dans chaque vue : un titre est un element de referencement, et l'oublier sur une page passe inapercu en relecture.

paginationInfo()

View Helpers Pagination Functions string controller

Displays a text summary of the current pagination state, e.g. "Showing 26-50 of 1,000 records". Uses token replacement in the format string:

Name Type Required Default Description
handle string No query The handle given to the query that the pagination info should be displayed for.
format string No Showing [startRow]-[endRow] of [totalRecords] records Format string with tokens: [startRow], [endRow], [totalRecords], [currentPage], [totalPages].
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
//--------------------------------------------------------------------
// Example 1: Basic usage — display the default summary text for a
// paginated query (e.g. "Showing 26-50 of 1,000 records")

// Controller code
param name="params.page" type="integer" default="1";
posts = model("Post").findAll(page=params.page, perPage=25, order="createdAt DESC");

// View code
<cfoutput>
    #paginationInfo()#
</cfoutput>
// -> "Showing 26-50 of 1,000 records"


//--------------------------------------------------------------------
// Example 2: Custom format string using available tokens
// Tokens: [startRow], [endRow], [totalRecords], [currentPage], [totalPages]

// View code
<cfoutput>
    #paginationInfo(format="Page [currentPage] of [totalPages] ([totalRecords] total)")#
</cfoutput>
// -> "Page 2 of 40 (1,000 total)"


//--------------------------------------------------------------------
// Example 3: Multiple paginated queries on the same page using handles

// Controller code
param name="params.postPage" type="integer" default="1";
param name="params.commentPage" type="integer" default="1";
posts    = model("Post").findAll(handle="posts", page=params.postPage, perPage=10, order="createdAt DESC");
comments = model("Comment").findAll(handle="comments", page=params.commentPage, perPage=5, order="createdAt DESC");

// View code
<cfoutput>
    Posts: #paginationInfo(handle="posts")#
    Comments: #paginationInfo(handle="comments")#
</cfoutput>
// -> "Posts: Showing 1-10 of 87 records"
// -> "Comments: Showing 1-5 of 342 records"

paginationNav()

View Helpers Pagination Functions string controller

Creates a complete pagination navigation element wrapping individual pagination helpers. Outputs a

passwordField()

View Helpers Form Object Functions string controller

Builds and returns a string containing a password field form control based on the supplied objectName and property. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
objectName any Yes The variable name of the object to build the form control for.
property string Yes The name of the property to use in the form control.
association string No The name of the association that the property is located on. Used for building nested forms that work with nested properties. If you are building a form with deep nesting, simply pass in a list to the nested object, and Wheels will figure it out.
position string No The position used when referencing a hasMany relationship in the association argument. Used for building nested forms that work with nested properties. If you are building a form with deep nestings, simply pass in a list of positions, and Wheels will figure it out.
label string No useDefaultLabel The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
errorElement string No span HTML tag to wrap the form control with when the object contains errors.
errorClass string No field-with-errors The class name of the HTML tag that wraps the form control when there are errors.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic password field bound to a `user` object
<cfoutput>
    #passwordField(objectName="user", property="password", label="Password")#
</cfoutput>
// -> <label for="user-password">Password<input id="user-password" type="password" name="user[password]" value=""></label>

// 2. Password field with a confirmation property on the same object
<cfoutput>
    #passwordField(objectName="user", property="password", label="Password")#
    #passwordField(objectName="user", property="passwordConfirmation", label="Confirm Password")#
</cfoutput>

// 3. Password fields for nested `passwords` association (hasMany)
<fieldset>
    <legend>Passwords</legend>
    <cfloop from="1" to="#ArrayLen(user.passwords)#" index="i">
        #passwordField(objectName="user", association="passwords", position=i, property="password", label="Password ##i#")#
    </cfloop>
</fieldset>

// 4. Wrap the field with custom HTML using `prepend` and `append`
<cfoutput>
    #passwordField(objectName="user", property="password", label="Password", prepend="<div class=""field"">", append="</div>")#
</cfoutput>

passwordFieldTag()

View Helpers Form Tag Functions string controller

Builds and returns a string containing a password field form control based on the supplied name. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
name string Yes Name to populate in tag's name attribute.
value string No Value to populate in tag's value attribute.
label string No The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic password field with just a name
<cfoutput>
    #passwordFieldTag(name="password")#
</cfoutput>
// -> <input type="password" name="password" id="password" value="">

// 2. With a label and a pre-filled value (e.g. re-displaying on validation error)
<cfoutput>
    #passwordFieldTag(name="password", label="Password", value=params.password)#
</cfoutput>
// -> <label for="password">Password<input type="password" name="password" id="password" value=""></label>

// 3. Label placed before the field, with HTML wrappers using prepend/append
<cfoutput>
    #passwordFieldTag(name="password", label="Password", labelPlacement="before", prepend="<div class=""field"">", append="</div>")#
</cfoutput>
// -> <div class="field"><label for="password">Password</label><input type="password" name="password" id="password" value=""></div>

patch()

Configuration Routing struct mapper

Create a route that matches a URL requiring an HTTP PATCH method. We recommend using this matcher to expose actions that update database records.

Name Type Required Default Description
name string No Camel-case name of route to reference when build links and form actions (e.g., blogPost).
pattern string No Overrides the URL pattern that will match the route. The default value is a dasherized version of name (e.g., a name of blogPost generates a pattern of blog-post).
to string No Set controller##action combination to map the route to. You may use either this argument or a combination of controller and action.
controller string No Map the route to a given controller. This must be passed along with the action argument.
action string No Map the route to a given action within the controller. This must be passed along with the controller argument.
package string No Indicates a subfolder that the controller will be referenced from (but not added to the URL pattern). For example, if you set this to admin, the controller will be located at admin/YourController.cfc, but the URL path will not contain admin/.
on string No If this route is within a nested resource, you can set this argument to member or collection. A member route contains a reference to the resource's key, while a collection route does not.
redirect string No Redirect via 302 to this URL when this route is matched. Has precedence over controller/action. Use either an absolute link like /about/, or a full canonical link.
<cfscript>

mapper()
    // Route name:  ghostStory
    // Example URL: /ghosts/666/stories/616
    // Controller:  Stories
    // Action:      update
    .patch(name="ghostStory", pattern="ghosts/[ghostKey]/stories/[key]", to="stories##update")

    // Route name:  goblins
    // Example URL: /goblins
    // Controller:  Goblins
    // Action:      update
    .patch(name="goblins", controller="goblins", action="update")

    // Route name:  heartbeat
    // Example URL: /heartbeat
    // Controller:  Sessions
    // Action:      update
    .patch(name="heartbeat", to="sessions##update")

    // Route name:  usersPreferences
    // Example URL: /preferences
    // Controller:  users.Preferences
    // Action:      update
    .patch(name="preferences", to="preferences##update", package="users")

    // Route name:  orderShipment
    // Example URL: /shipments/5432
    // Controller:  orders.Shipments
    // Action:      update
    .patch(
        name="shipment",
        pattern="shipments/[key]",
        to="shipments##update",
        package="orders"
    )

    // Redirect a legacy PATCH endpoint to the canonical URL
    // Example URL: /accounts/[key]/edit -> redirects to /users/[key]/edit
    .patch(name="legacyAccount", pattern="accounts/[key]/edit", redirect="/users/[key]/edit")

    // Example scoping within a nested resource
    .resources(name="subscribers", nested=true)
        // Route name:  launchSubscribers
        // Example URL: /subscribers/3209/launch
        // Controller:  Subscribers
        // Action:      update
        .patch(name="launch", to="subscribers##update", on="collection")

        // Route name:  discontinueSubscriber
        // Example URL: /subscribers/2251/discontinue
        // Controller:  Subscribers
        // Action:      discontinue
        .patch(name="discontinue", to="subscribers##discontinue", on="member")
    .end()
.end();

</cfscript>

pluginNames()

Global Helpers Miscellaneous Functions string controller model mapper migrator migration tabledefinition

Returns a list of the names of all installed plugins.

// 1. Check if the Scaffold plugin is installed
<cfif listFindNoCase(pluginNames(), "scaffold")>
    // do something cool
</cfif>

// 2. Output all installed plugin names
names = pluginNames();
// names -> "scaffold,formobject,myplugin" (comma-separated list of installed plugin names)

// 3. Loop over installed plugins
<cfloop list="#pluginNames()#" index="pluginName">
    writeOutput(pluginName);
</cfloop>

pluralize()

Global Helpers String Functions string controller model mapper migrator migration tabledefinition

Returns the plural form of the passed in word. Can also pluralize a word based on a value passed to the count argument. Wheels stores a list of words that are the same in both singular and plural form (e.g. "equipment", "information") and words that don't follow the regular pluralization rules (e.g. "child" / "children", "foot" / "feet"). Use get("uncountables") / set("uncountables", newList) and get("irregulars") / set("irregulars", newList) to modify them to suit your needs.

Name Type Required Default Description
word string Yes The word to pluralize.
count numeric No -1 Pluralization will occur when this value is not 1.
returnCount boolean No true Will return count prepended to the pluralization when true and count is not -1.
// 1. Pluralize a word using standard rules
writeOutput(pluralize("person"));
// -> "people"

// 2. Pluralize based on a count; returns count prepended to the word
writeOutput(pluralize(word="comment", count=1));
// -> "1 comment"

writeOutput(pluralize(word="comment", count=5));
// -> "5 comments"

// 3. Pluralize based on a count but omit the count from the output
writeOutput(pluralize(word="person", count=users.RecordCount, returnCount=false));
// -> "people" (when RecordCount != 1) or "person" (when RecordCount == 1)

policyScope()

Controller Authorization Functions any controller

Narrows a collection to the records the current user may see by delegating to the policy's scope() method. Returns whatever the policy returns — conventionally a chainable finder you keep composing: function index() { posts = policyScope(model("Post")).findAll(page = params.page, perPage = 25); } Pass the model class first and chain scopes after the call (policyScope(model("Post")).active()) — a query-builder or scope chain that is already in flight cannot be introspected for its model. When the policy class is missing, this throws Wheels.Policy.NotDefined in development/testing and returns a default-deny (no rows) chain in production.

Name Type Required Default Description
collection any Yes The model class to narrow.

post()

Configuration Routing struct mapper

Create a route that matches a URL requiring an HTTP POST method. We recommend using this matcher to expose actions that create database records.

Name Type Required Default Description
name string No Camel-case name of route to reference when build links and form actions (e.g., blogPosts).
pattern string No Overrides the URL pattern that will match the route. The default value is a dasherized version of name (e.g., a name of blogPosts generates a pattern of blog-posts).
to string No Set controller##action combination to map the route to. You may use either this argument or a combination of controller and action.
controller string No Map the route to a given controller. This must be passed along with the action argument.
action string No Map the route to a given action within the controller. This must be passed along with the controller argument.
package string No Indicates a subfolder that the controller will be referenced from (but not added to the URL pattern). For example, if you set this to admin, the controller will be located at admin/YourController.cfc, but the URL path will not contain admin/.
on string No If this route is within a nested resource, you can set this argument to member or collection. A member route contains a reference to the resource's key, while a collection route does not.
redirect string No Redirect via 302 to this URL when this route is matched. Has precedence over controller/action. Use either an absolute link like /about/, or a full canonical link.
<cfscript>

mapper()
    // 1. Basic POST route using `to` shorthand (controller##action)
    // Route name:  widgets
    // Example URL: /sites/918/widgets
    // Controller:  Widgets
    // Action:      create
    .post(name="widgets", pattern="sites/[siteKey]/widgets", to="widgets##create")

    // 2. POST route using explicit `controller` and `action` arguments
    // Route name:  wadgets
    // Example URL: /wadgets
    // Controller:  Wadgets
    // Action:      create
    .post(name="wadgets", controller="wadgets", action="create")

    // 3. POST route with a custom URL pattern (e.g., format-bearing endpoint)
    // Route name:  authenticate
    // Example URL: /oauth/token.json
    // Controller:  Tokens
    // Action:      create
    .post(name="authenticate", pattern="oauth/token.json", to="tokens##create")

    // 4. POST route scoped to a package (subfolder) — package not in URL
    // Route name:  usersPreferences
    // Example URL: /preferences
    // Controller:  users.Preferences
    // Action:      create
    .post(name="preferences", to="preferences##create", package="users")

    // 5. POST route with both a custom pattern and a package
    // Route name:  extranetOrders
    // Example URL: /buy-now/orders
    // Controller:  extranet.Orders
    // Action:      create
    .post(
        name="orders",
        pattern="buy-now/orders",
        to="orders##create",
        package="extranet"
    )

    // 6. POST route that issues a 302 redirect instead of dispatching to a controller
    // Route name:  legacySignup
    // Example URL: /signup  →  redirects to /register
    .post(name="legacySignup", pattern="signup", redirect="/register")

    // 7. POST routes nested inside a `resources` block using `on`
    .resources(name="customers", nested=true)
        // Route name:  leadsCustomers
        // Example URL: /customers/leads
        // Controller:  Leads
        // Action:      create
        .post(name="leads", to="leads##create", on="collection")

        // Route name:  cancelCustomer
        // Example URL: /customers/3209/cancel
        // Controller:  Cancellations
        // Action:      create
        .post(name="cancel", to="cancellations##create", on="member")
    .end()
.end();

</cfscript>

pretendVersion()

Migrator General Functions struct migrator

Records a version as applied in wheels_migrator_versions without running its up() method. Useful when a peer applied the migration via direct SQL or a different tool and you need the tracking table to reflect that. Refuses if the version is already applied, or if no local file matches (only known versions can be pretended). Returns: {success, recorded, message}

Name Type Required Default Description
version string Yes The version string to record (digits only after sanitisation).

primaryKey()

Model Class Miscellaneous Functions string model

Returns the name of the primary key for this model's table. This is determined through database introspection. If composite primary keys have been used, they will both be returned in a list. This function is also aliased as primaryKeys().

Name Type Required Default Description
position numeric No 0 If you are accessing a composite primary key, pass the position of a single key to fetch.
// 1. Get the name of the primary key for the `employee` model (maps to the `employees` table by default)
keyName = model("employee").primaryKey();
// keyName -> "id"

// 2. Get all primary key column names for a model with a composite primary key
keys = model("orderItem").primaryKey();
// keys -> "orderId,productId"

// 3. Get only the first key of a composite primary key using the `position` argument
firstKey = model("orderItem").primaryKey(1);
// firstKey -> "orderId"

// 4. Use the `primaryKeys()` alias (preferred for readability with composite keys)
keys = model("orderItem").primaryKeys();
// keys -> "orderId,productId"

primaryKey()

Migrator Table Definition Functions any tabledefinition

Adds a primary key definition to the table. this method also allows for multiple primary keys. Accepts columnName / columnNames as aliases for name (per #2803) so the PK helper matches the argument-naming convention every other column helper in this file uses. The legacy name parameter keeps working — it is still what the body reads and what init() passes when adding the conventional id primary key.

Name Type Required Default Description
name string No Legacy parameter for the primary-key column name. New code should prefer columnName.
columnName string No Modern singular alias for name (matches sibling column helpers).
columnNames string No Modern plural alias for name. Accepted for muscle-memory parity with t.integer(columnNames=...) etc. NOTE: unlike sibling helpers, this does NOT accept a comma-separated list — primaryKey() always creates one PK column, so columnNames="a,b" produces a single column literally named a,b (not two PKs). For composite PKs call t.primaryKey() multiple times.
type string No integer
autoIncrement boolean No false
limit numeric No
precision numeric No
scale numeric No
references string No
onUpdate string No
onDelete string No

primaryKeys()

Model Class Miscellaneous Functions string model

Alias for primaryKey(). Use this for better readability when you're accessing multiple primary keys.

Name Type Required Default Description
position numeric No 0 If you are accessing a composite primary key, pass the position of a single key to fetch.
// 1. Get the name(s) of the primary key(s) for the User model (returns a comma-separated list for composite keys)
keyNames = model("User").primaryKeys();
// keyNames -> "id"

// 2. Get the name of the first primary key in a model that uses a composite primary key (e.g., an OrderItem table keyed on orderId,productId)
firstKey = model("OrderItem").primaryKeys(1);
// firstKey -> "orderId"

// 3. Get the second primary key in a composite key model
secondKey = model("OrderItem").primaryKeys(2);
// secondKey -> "productId"

processAction()

Controller Miscellaneous Functions boolean controller

Process the specified action of the controller. This is exposed in the API primarily for testing purposes; you would not usually call it directly unless in the test suite.

Name Type Required Default Description
includeFilters string No true Set to before to only execute "before" filters, after to only execute "after" filters or false to skip all filters. This argument is generally inherited from the processRequest function during unit test execution.
// 1. Process the current action (runs before and after filters plus the action itself).
// Typically called automatically by the framework; used directly in unit tests.
result = controller.processAction();
// result -> true

// 2. Process the action running only "before" filters (skip "after" filters).
result = controller.processAction(includeFilters="before");
// result -> true

// 3. Process the action without running any filters.
result = controller.processAction(includeFilters=false);
// result -> true

processRequest()

Controller Miscellaneous Functions any controller model mapper migrator migration tabledefinition

Creates a controller and calls an action on it. Which controller and action that's called is determined by the params passed in. Returns the result of the request either as a string or in a struct with body, emails, files, flash, redirect, status, and type. Primarily used for testing purposes.

Name Type Required Default Description
params struct Yes The params struct to use in the request (make sure that at least controller and action are set).
method string No get The HTTP method to use in the request (get, post etc).
returnAs string No Pass in struct to return all information about the request instead of just the final output (body).
rollback string No false Pass in true to roll back all database transactions made during the request.
includeFilters string No true Set to before to only execute "before" filters, after to only execute "after" filters or false to skip all filters.
// 1. Basic usage: simulate a GET request to the Users#index action and return the rendered body.
result = processRequest(params={controller="users", action="index"});
// result -> "<html>...</html>"

// 2. Simulate a POST request to create a new user and return the full response struct.
result = processRequest(
    params={controller="users", action="create", firstName="Jane", lastName="Doe"},
    method="post",
    returnAs="struct"
);
// result.status   -> 302
// result.redirect -> "/users"
// result.body     -> ""
// result.flash    -> {success="User created."}

// 3. Roll back all database changes made during the request (useful in tests to keep data clean).
result = processRequest(
    params={controller="users", action="create", firstName="Jane"},
    method="post",
    rollback=true,
    returnAs="struct"
);
// result.status -> 302

// 4. Run the action without any filters (bypass before/after filter logic).
result = processRequest(
    params={controller="users", action="index"},
    includeFilters=false
);
// result -> "<html>...</html>"

projectContext()

string controller

Contexte d'un projet sous forme lisible. La base separe le libelle et l'annee — c'est ce qui rend l'annee triable. La recomposition pour l'affichage se fait donc ici, en un seul endroit.

Name Type Required Default Description
context any No [runtime expression]

properties()

Model Object Miscellaneous Functions struct model

Returns a structure of all the properties with their names as keys and the values of the property as values.

Name Type Required Default Description
returnIncluded boolean No true Whether to return nested properties or not.
// 1. Get all properties of a model object as a struct
user = model("User").findByKey(1);
props = user.properties();
// props -> {id: 1, firstName: "Jane", lastName: "Doe", email: "jane@example.com", createdAt: ...}

// 2. Exclude nested (included) association properties from the result
// Useful when you only want the object's own scalar properties
post = model("Post").findOne(include="comments");
ownProps = post.properties(returnIncluded=false);
// ownProps -> {id: 42, title: "Hello World", body: "...", createdAt: ...}
// (nested `comments` array is omitted)

// 3. Use properties() to pass a model's data as a plain struct (e.g. to a service layer)
user = model("User").findByKey(session.userId);
userService.syncUser(user.properties());

property()

Model Configuration Miscellaneous Functions void model

Use this method to map an object property to either a table column with a different name than the property or to a SQL expression. You only need to use this method when you want to override the default object relational mapping that Wheels performs.

Name Type Required Default Description
name string Yes The name that you want to use for the column or SQL function result in the CFML code.
column string No The name of the column in the database table to map the property to.
sql string No An SQL expression to use to calculate the property value.
label string No A custom label for this property to be referenced in the interface and error messages.
defaultValue string No A default value for this property.
select boolean No true Whether to include this property by default in SELECT statements
dataType string No char Specify the column dataType for this property
automaticValidations boolean No Enable / disable automatic validations for this property.
// 1. Map a CFML property name to a differently-named database column
// Tell Wheels that `firstName` in CFML maps to `STR_USERS_FNAME` in the database
// instead of the default `firstname` column
property(name="firstName", column="STR_USERS_FNAME");

// 2. Create a calculated property using a SQL expression
// `fullName` is derived by concatenating two columns at the database level
property(name="fullName", sql="STR_USERS_FNAME + ' ' + STR_USERS_LNAME");

// 3. Set a custom label used in form helpers and validation error messages
property(name="firstName", label="First name(s)");

// 4. Specify a default value applied when creating new objects
property(name="firstName", defaultValue="Dave");

// 5. Define a calculated property with a specific data type and exclude it from default SELECTs
// Useful when the SQL expression returns a numeric result or when you only need
// the value in specific queries
property(name="orderTotal", sql="SUM(line_items.price)", dataType="decimal", select=false);

// 6. Disable automatic validations for a specific property
// Wheels normally infers validations (e.g. string-length, numeric) from the column type;
// set automaticValidations=false to skip that for this property
property(name="legacyCode", automaticValidations=false);

propertyIsBlank()

Model Object Miscellaneous Functions boolean model

Returns true if the specified property doesn't exist on the model or is an empty string. This method is the inverse of propertyIsPresent().

Name Type Required Default Description
property string Yes Name of property to inspect.
// 1. Check if a property is blank before sending a notification
user = model("User").findByKey(params.userId);
if (user.propertyIsBlank("email")) {
    flashInsert(error="Please provide an email address before continuing.");
}

// 2. Conditionally set a default value when a property is blank
product = model("Product").findByKey(params.id);
if (product.propertyIsBlank("description")) {
    product.description = "No description available.";
    product.save();
}

// 3. Use propertyIsBlank alongside its inverse propertyIsPresent for branching logic
post = model("Post").findByKey(params.postId);
if (post.propertyIsBlank("publishedAt")) {
    // post has never been published
    writeOutput("Draft");
} else {
    // propertyIsPresent("publishedAt") would return true here
    writeOutput("Published on #post.publishedAt#");
}

propertyIsPresent()

Model Object Miscellaneous Functions boolean model

Returns true if the specified property exists on the model and is not a blank string.

Name Type Required Default Description
property string Yes Name of property to inspect.
// 1. Check if a non-blank property is present
employee = model("Employee").new();
employee.firstName = "Jane";
writeOutput(employee.propertyIsPresent("firstName")); // true

// 2. Returns false when the property is an empty string
employee = model("Employee").new();
employee.firstName = "";
writeOutput(employee.propertyIsPresent("firstName")); // false

// 3. Returns false when the property does not exist on the object
employee = model("Employee").new();
writeOutput(employee.propertyIsPresent("nonExistentField")); // false

propertyNames()

Model Class Miscellaneous Functions string model

Returns a list of property names ordered by their respective column's ordinal position in the database table. Also includes calculated property names that will be generated by the Wheels ORM.

// 1. Get a comma-delimited list of all property names for the User model
propNames = model("User").propertyNames();
// propNames -> "id,firstName,lastName,email,createdAt,updatedAt"

// 2. Check whether a specific property exists on the model before accessing it
propNames = model("User").propertyNames();
if (listFindNoCase(propNames, "email")) {
    writeOutput("email is a valid property");
}

// 3. Property names include calculated properties defined with property(sql="...")
// In User.cfc config():
//   property(name="fullName", sql="firstName || ' ' || lastName");
propNames = model("User").propertyNames();
// propNames -> "id,firstName,lastName,email,createdAt,updatedAt,fullName"

protectedProperties()

Model Configuration Miscellaneous Functions void model

Use this method to specify which properties cannot be set through mass assignment.

Name Type Required Default Description
properties string No Property name (or list of property names) that are not allowed to be altered through mass assignment.
// 1. Protect a comma-delimited list of properties from mass assignment in `models/User.cfc`.
// `firstName` and `lastName` cannot be changed via `updateAll()`, `new()`, `update()`, etc.
function config() {
	protectedProperties("firstName,lastName");
}

// 2. Using the named argument form to protect sensitive fields like `role` and `isAdmin`
function config() {
	protectedProperties(properties="role,isAdmin");
}

protectsFromForgery()

Controller Configuration Functions any controller

Tells Wheels to protect POSTed requests from CSRF vulnerabilities. Instructs the controller to verify that params.authenticityToken or X-CSRF-Token HTTP header is provided along with the request containing a valid authenticity token. Call this method within a controller's config method, preferably the base Controller.cfc file, to protect the entire application.

Name Type Required Default Description
with string No exception How to handle invalid authenticity token checks. Valid values are exception (the default — throws a Wheels.InvalidAuthenticityToken error), abort (aborts the request silently and sends a blank response to the client), and ignore (ignores the check and lets the request proceed).
only string No List of actions that this check should only run on. Leave blank for all.
except string No List of actions that this check should be omitted from running on. Leave blank for no exceptions.
// 1. Protect all POST actions across the entire application (add to the base Controller.cfc).
component extends="Controller" {
    function config() {
        protectsFromForgery();
    }
}

// 2. Abort silently on an invalid token instead of throwing an exception.
component extends="Controller" {
    function config() {
        protectsFromForgery(with="abort");
    }
}

// 3. Enable CSRF protection only on state-changing actions.
component extends="Controller" {
    function config() {
        protectsFromForgery(only="create, update, delete");
    }
}

// 4. Enable CSRF protection globally but skip it for a public API endpoint.
component extends="Controller" {
    function config() {
        protectsFromForgery(except="apiReceive");
    }
}

provides()

Controller Configuration Functions void controller

Defines formats that the controller will respond with upon request. The format can be requested through a URL variable called format, by appending the format name to the end of a URL as an extension (when URL rewriting is enabled), or in the request header.

Name Type Required Default Description
formats string No Formats to instruct the controller to provide. Valid values are html (the default), xml, json, csv, pdf, and xls.
// 1. Allow the controller to respond to HTML and JSON requests
// Place this call inside the controller's config() function
provides("html,json");

// 2. Allow all supported formats for an API controller
provides("html,xml,json,csv,pdf,xls");

// 3. JSON-only controller (e.g. a pure REST API controller)
// Any request for a format other than json will be rejected
provides("json");

publish()

Global Helpers Channel Functions struct controller model mapper migrator migration tabledefinition

Publish an event to a channel. Delegates to the in-memory Channel engine or the DatabaseAdapter depending on the adapter argument (or the global channelAdapter setting). Can be called from controllers, models, jobs, or anywhere with access to global helpers.

Name Type Required Default Description
channel string Yes The channel name to publish to (e.g. "user.42").
event string Yes The event type (e.g. "notification", "update").
data string Yes The event data as a string (typically JSON).
adapter string No Adapter to use: "memory" (default) or "database".
// 1. Publish a notification event to a user-specific channel (in-memory adapter)
data = serializeJSON({message = "Your order has shipped!", orderId = 42});
result = publish(channel="user.42", event="notification", data=data);
// result -> {success: true, ...}

// 2. Publish an update event using the database adapter for persistence
data = serializeJSON({status = "active", updatedAt = Now()});
result = publish(channel="products", event="update", data=data, adapter="database");

// 3. Broadcast a chat message to a room channel
result = publish(
    channel = "chat.room.5",
    event   = "message",
    data    = serializeJSON({user = "alice", text = "Hello everyone!"})
);

put()

Configuration Routing struct mapper

Create a route that matches a URL requiring an HTTP PUT method. We recommend using this matcher to expose actions that update database records. This method is provided as a convenience for when you really need to support the PUT verb; consider using the patch matcher instead of this one.

Name Type Required Default Description
name string No Camel-case name of route to reference when build links and form actions (e.g., blogPost).
pattern string No Overrides the URL pattern that will match the route. The default value is a dasherized version of name (e.g., a name of blogPost generates a pattern of blog-post).
to string No Set controller##action combination to map the route to. You may use either this argument or a combination of controller and action.
controller string No Map the route to a given controller. This must be passed along with the action argument.
action string No Map the route to a given action within the controller. This must be passed along with the controller argument.
package string No Indicates a subfolder that the controller will be referenced from (but not added to the URL pattern). For example, if you set this to admin, the controller will be located at admin/YourController.cfc, but the URL path will not contain admin/.
on string No If this route is within a nested resource, you can set this argument to member or collection. A member route contains a reference to the resource's key, while a collection route does not.
redirect string No Redirect via 302 to this URL when this route is matched. Has precedence over controller/action. Use either an absolute link like /about/, or a full canonical link.
<cfscript>

mapper()
    // 1. Basic PUT route using "to" shorthand (controller##action)
    // Route name:  ghostStory
    // Example URL: /ghosts/666/stories/616
    // Controller:  Stories
    // Action:      update
    .put(name="ghostStory", pattern="ghosts/[ghostKey]/stories/[key]", to="stories##update")

    // 2. Explicit controller and action arguments
    // Route name:  goblins
    // Example URL: /goblins
    // Controller:  Goblins
    // Action:      update
    .put(name="goblins", controller="goblins", action="update")

    // 3. Minimal "to" — pattern derived from name
    // Route name:  heartbeat
    // Example URL: /heartbeat
    // Controller:  Sessions
    // Action:      update
    .put(name="heartbeat", to="sessions##update")

    // 4. Scoped to a package (subfolder) — package not added to URL
    // Route name:  usersPreferences
    // Example URL: /preferences
    // Controller:  users.Preferences
    // Action:      update
    .put(name="preferences", to="preferences##update", package="users")

    // 5. Package combined with an explicit pattern
    // Route name:  orderShipment
    // Example URL: /shipments/5432
    // Controller:  orders.Shipments
    // Action:      update
    .put(
        name="shipment",
        pattern="shipments/[key]",
        to="shipments##update",
        package="orders"
    )

    // 6. Permanent redirect — useful when an endpoint has moved
    // Example URL: /legacy-profile -> redirects to /profile
    .put(name="legacyProfile", pattern="legacy-profile", redirect="/profile")

    // 7. "on" argument within a nested resource
    .resources(name="subscribers", nested=true)
        // Route name:  launchSubscribers
        // Example URL: /subscribers/launch
        // Controller:  Subscribers
        // Action:      launch
        .put(name="launch", to="subscribers##launch", on="collection")

        // Route name:  discontinueSubscriber
        // Example URL: /subscribers/2251/discontinue
        // Controller:  Subscribers
        // Action:      discontinue
        .put(name="discontinue", to="subscribers##discontinue", on="member")
    .end()
.end();

</cfscript>

radioButton()

View Helpers Form Object Functions string controller

Builds and returns a string containing a radio button form control based on the supplied objectName and property. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
objectName any Yes The variable name of the object to build the form control for.
property string Yes The name of the property to use in the form control.
association string No The name of the association that the property is located on. Used for building nested forms that work with nested properties. If you are building a form with deep nesting, simply pass in a list to the nested object, and Wheels will figure it out.
position string No The position used when referencing a hasMany relationship in the association argument. Used for building nested forms that work with nested properties. If you are building a form with deep nestings, simply pass in a list of positions, and Wheels will figure it out.
tagValue string No The value of the radio button when selected.
label string No useDefaultLabel The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
errorElement string No span HTML tag to wrap the form control with when the object contains errors.
errorClass string No field-with-errors The class name of the HTML tag that wraps the form control when there are errors.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic radio buttons for a gender property on a user object
<cfoutput>
	<fieldset>
		<legend>Gender</legend>
		#radioButton(objectName="user", property="gender", tagValue="m", label="Male")#
		#radioButton(objectName="user", property="gender", tagValue="f", label="Female")#
	</fieldset>
</cfoutput>

// 2. Radio buttons with label placed after the control and a CSS class applied
<cfoutput>
	#radioButton(objectName="user", property="status", tagValue="active", label="Active", labelPlacement="after", class="status-radio")#
	#radioButton(objectName="user", property="status", tagValue="inactive", label="Inactive", labelPlacement="after", class="status-radio")#
</cfoutput>

// 3. Radio buttons for a nested hasMany association (e.g. setting each committee member's gender)
<cfoutput>
	<cfloop from="1" to="#ArrayLen(committee.members)#" index="i">
		<div>
			<h3>#committee.members[i].fullName#:</h3>
			#radioButton(objectName="committee", association="members", position=i, property="gender", tagValue="m", label="Male")#
			#radioButton(objectName="committee", association="members", position=i, property="gender", tagValue="f", label="Female")#
		</div>
	</cfloop>
</cfoutput>

radioButtonTag()

View Helpers Form Tag Functions string controller

Builds and returns a string containing a radio button form control based on the supplied name. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
name string Yes Name to populate in tag's name attribute.
value string Yes Value to populate in tag's value attribute.
checked boolean No false Whether or not to check the radio button by default.
label string No The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic usage with a group of radio buttons sharing the same name
<cfoutput>
	<fieldset>
		<legend>Gender</legend>
		#radioButtonTag(name="gender", value="m", label="Male", checked=true)#
		#radioButtonTag(name="gender", value="f", label="Female")#
	</fieldset>
</cfoutput>

// 2. Place the label after the radio button instead of wrapping it
<cfoutput>
	#radioButtonTag(name="size", value="s", label="Small", labelPlacement="after")#
	#radioButtonTag(name="size", value="m", label="Medium", labelPlacement="after")#
	#radioButtonTag(name="size", value="l", label="Large", labelPlacement="after")#
</cfoutput>

// 3. Loop over a query to render one radio button per option
// Controller
sizes = model("Size").findAll(order="position");

// View
<cfoutput query="sizes">
	#radioButtonTag(
		name   = "sizeId",
		value  = sizes.id,
		label  = sizes.name,
		checked = sizes.id EQ params.sizeId
	)#
</cfoutput>

rangeField()

View Helpers Form Object Functions string controller

Builds and returns a string containing a range slider form control based on the supplied objectName and property. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
objectName any Yes The variable name of the object to build the form control for.
property string Yes The name of the property to use in the form control.
association string No The name of the association that the property is located on. Used for building nested forms that work with nested properties. If you are building a form with deep nesting, simply pass in a list to the nested object, and Wheels will figure it out.
position string No The position used when referencing a hasMany relationship in the association argument. Used for building nested forms that work with nested properties. If you are building a form with deep nestings, simply pass in a list of positions, and Wheels will figure it out.
min string No Minimum allowed value.
max string No Maximum allowed value.
step string No Stepping interval.
label string No useDefaultLabel The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
errorElement string No span HTML tag to wrap the form control with when the object contains errors.
errorClass string No field-with-errors The class name of the HTML tag that wraps the form control when there are errors.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic range slider bound to a model object
#rangeField(objectName="settings", property="volume")#

// 2. Range slider with min, max, and step constraints
#rangeField(label="Volume", objectName="settings", property="volume", min="0", max="100", step="5")#

// 3. Range slider for a nested association (preferences within a user profile)
<cfloop from="1" to="#ArrayLen(user.preferences)#" index="i">
	#rangeField(label="Threshold ##i#", objectName="user", association="preferences", position=i, property="threshold", min="0", max="10", step="1")#
</cfloop>

rangeFieldTag()

View Helpers Form Tag Functions string controller

Builds and returns a string containing a range slider form control based on the supplied name. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
name string Yes Name to populate in tag's name attribute.
value string No Value to populate in tag's value attribute.
min string No Minimum allowed value.
max string No Maximum allowed value.
step string No Stepping interval.
label string No The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic range slider with a name and current value
#rangeFieldTag(name="volume", value=params.volume)#

// 2. Range slider with min, max, and step constraints plus a label
#rangeFieldTag(name="brightness", value=params.brightness, label="Brightness", min="0", max="100", step="5")#

// 3. Range slider with a CSS class and appended display hint
#rangeFieldTag(name="opacity", value=params.opacity, label="Opacity", min="0", max="1", step="0.1", class="opacity-slider", append="(0–1)")#

redirectTo()

Controller Miscellaneous Functions void controller

Redirects the browser to the supplied controller/action/key, route or back to the referring page. Internally, this function uses the URLFor function to build the link and the cflocation tag to perform the redirect.

Name Type Required Default Description
back boolean No false Set to true to redirect back to the referring page.
addToken boolean No false See documentation for your CFML engine's implementation of cflocation.
statusCode numeric No 302 See documentation for your CFML engine's implementation of cflocation.
route string No Name of a route that you have configured in config/routes.cfm.
method string No HTTP method constraint used when matching routes.
controller string No Name of the controller to include in the URL.
action string No Name of the action to include in the URL.
key any No Key(s) to include in the URL.
params string No Any additional parameters to be set in the query string (example: wheels=cool&x=y). Please note that Wheels uses the & and = characters to split the parameters and encode them properly for you. However, if you need to pass in & or = as part of the value, then you need to encode them (and only them), example: a=cats%26dogs%3Dtrouble!&b=1.
anchor string No Sets an anchor name to be appended to the path.
onlyPath boolean No true If true, returns only the relative URL (no protocol, host name or port).
host string No Set this to override the current host.
protocol string No Set this to override the current protocol.
port numeric No 0 Set this to override the current port number.
url string No Redirect to an external URL.
delay boolean No false Set to true to delay the redirection until after the rest of your action code has executed.
encode boolean No true Encode URL parameters using EncodeForURL(). Please note that this does not make the string safe for placement in HTML attributes, for that you need to wrap the result in EncodeForHtmlAttribute() or use linkTo(), startFormTag() etc instead.
// 1. Redirect to an action after successfully saving a user.
if (user.save()) {
	redirectTo(action="saveSuccessful");
}

// 2. Redirect to a different controller and action on a secure server with extra query params.
redirectTo(controller="checkout", action="start", params="type=express", protocol="https");

// 3. Redirect to a named route and pass in a dynamic route variable.
redirectTo(route="profile", screenName="Joe");

// 4. Redirect back to the referring page (e.g. after a cancelled edit).
redirectTo(back=true);

// 5. Redirect to an external URL (requires allowExternalRedirects=true in config).
redirectTo(url="https://example.com/landing");

// 6. Delay the redirect until after the rest of the action has run, and set a flash message.
redirectTo(action="index", delay=true, flashMessage="Record deleted successfully.");

// 7. Use a 301 permanent redirect when moving a page.
redirectTo(controller="posts", action="index", statusCode=301);

redoMigration()

Migrator General Functions string migrator

Reruns the specified migration version. Whilst you can use this in your application, the recommended usage is via either the CLI or the provided GUI interface

Name Type Required Default Description
version string No The Database schema version to rerun
// 1. Redo the current (most recent) migration — rolls it back then re-applies it
result = application.wheels.migrator.redoMigration();
// result -> "
// ------- 20240315120000_add_status_to_orders ----------------------
// "

// 2. Redo a specific migration version
result = application.wheels.migrator.redoMigration(version="20240101000000");
// result -> "
// ------- 20240101000000_create_users ------------------------------
// "

// 3. Check for errors after redoing a migration
result = application.wheels.migrator.redoMigration(version="20240315120000");
if (FindNoCase("Error", result)) {
    writeOutput("Redo failed: " & result);
} else {
    writeOutput("Migration redone successfully.");
}

references()

Migrator Table Definition Functions any tabledefinition

Adds integer reference columns to the table definition and (unless foreignKey=false or polymorphic=true) registers a matching foreign-key constraint. The column suffix depends on the useUnderscoreReferenceColumns setting: false (framework default) → id; true (default for apps generated by wheels new) → _id, matching Wheels model belongsTo defaults. With polymorphic=true, a type / _type companion column is added and no FK is registered. Accepts columnNames as an alias for referenceNames (per #2781) — both are list-shaped (single name or comma-delimited). New code should use columnNames for consistency with every other column helper here.

Name Type Required Default Description
referenceNames string No Comma-delimited list of reference base names (e.g. "user,role"). Each produces a _id (or id) column. Legacy parameter — columnNames is the modern alias.
columnNames string No Modern alias for referenceNames. Pass one or the other — not both.
default any No Default value for the generated integer column(s).
allowNull boolean No false If true, the generated column(s) allow NULL.
polymorphic boolean No false If true, also creates a type / _type companion column and skips the foreign-key constraint.
foreignKey boolean No true If true (default), registers a foreign key on the generated column. Ignored when polymorphic=true.
onUpdate string No Foreign-key ON UPDATE clause. Engine-specific values; common: "cascade", "null", "none".
onDelete string No Foreign-key ON DELETE clause. Same value set as onUpdate.
// The generated column suffix depends on the `useUnderscoreReferenceColumns` setting:
// `true` (the default for apps generated by `wheels new`) produces `<name>_id` / `<name>_type`,
// matching Wheels model `belongsTo` defaults; `false` (the framework default for existing apps)
// produces `<name>id` / `<name>type`. The examples below show both outcomes.

// 1. Add a single reference column with a foreign key constraint
// Creates a `user_id` (or `userid`) integer column and a foreign key pointing to the `users` table.
t = createTable(name='posts');
	t.string(columnNames='title', limit=255, allowNull=false);
	t.references(columnNames='user');
	t.timestamps();
t.create();

// 2. Add multiple reference columns at once
// Creates `author_id` and `category_id` (or `authorid` and `categoryid`) integer columns,
// each with a foreign key.
t = createTable(name='articles');
	t.string(columnNames='title', limit=255, allowNull=false);
	t.references(columnNames='author,category');
	t.timestamps();
t.create();

// 3. Add a polymorphic reference (no foreign key, adds a `<name>_type` / `<name>type` string column)
// Creates `commentable_id` (integer) and `commentable_type` (string) columns
// (or `commentableid` / `commentabletype` when `useUnderscoreReferenceColumns` is `false`).
t = createTable(name='comments');
	t.text(columnNames='body', allowNull=false);
	t.references(columnNames='commentable', polymorphic=true);
	t.timestamps();
t.create();

// 4. Add a reference with cascade delete and allow null
// The legacy `referenceNames=` argument is still accepted as an alias for `columnNames=`.
t = createTable(name='attachments');
	t.references(columnNames='post', allowNull=true, onDelete='cascade');
	t.string(columnNames='fileName', limit=255);
	t.timestamps();
t.create();

refLabel()

string controller

Libelle d'une valeur de reference, ou une chaine vide.

Name Type Required Default Description
valeur any No [runtime expression]

registerOnError()

Configuration Error Handling void controller model mapper migrator migration tabledefinition

Registers a callback function to be invoked when an unhandled error occurs. Callbacks receive a single argument: the exception struct. Multiple callbacks are invoked in registration order. A failing callback is logged and skipped — it will not prevent other callbacks from running. Should be called during app initialization, not per-request.

Name Type Required Default Description
callback function Yes A function that accepts an exception struct argument. Must complete quickly — long-running callbacks delay error responses.
// 1. Register a simple error-notification callback in config/settings.cfm
registerOnError(function(exception) {
    writeLog(
        file = "app-errors",
        type = "error",
        text = "Unhandled error: #exception.message# | Type: #exception.type#"
    );
});

// 2. Register multiple callbacks — they fire in registration order
registerOnError(function(exception) {
    // Notify an external monitoring service
    local.payload = serializeJSON({
        message = exception.message,
        type    = exception.type,
        detail  = exception.detail
    });
    // cfhttp call to monitoring endpoint would go here
});

registerOnError(function(exception) {
    // Store the last error in the application scope for the admin dashboard
    application.lastError = {
        message   = exception.message,
        type      = exception.type,
        timestamp = now()
    };
});

// 3. Guard against slow operations — callbacks must complete quickly
registerOnError(function(exception) {
    // Do NOT perform long-running tasks here (database queries, large file I/O).
    // A failing callback is caught, logged, and skipped so other callbacks still run.
    if (structKeyExists(exception, "message") && len(exception.message)) {
        writeLog(file = "wheels", type = "error", text = "App error: #exception.message#");
    }
});

reglage()

string controller

Valeur d'un reglage du site, avec repli. Le repli n'est pas decoratif : un reglage vide ou une API muette ne doivent pas produire une page trouee.

Name Type Required Default Description
code string Yes
defaut string No

reload()

Model Object Miscellaneous Functions void model

Reloads the property values of this object from the database.

// 1. Reload after a call that may have changed values in the database
employee = model("Employee").findByKey(params.key);
employee.someCallThatChangesValuesInTheDatabase();
employee.reload();

// 2. Discard in-memory changes and restore the current database values
post = model("Post").findByKey(params.id);
post.title = "Draft title that we want to discard";
post.reload();
// post.title now reflects the value stored in the database

removeColumn()

Migrator Migration Functions void migration

Removes a column from a database table Only available in a migration CFC

Name Type Required Default Description
table string Yes The table containing the column to remove
columnName string No The column name to remove
columnNames string No Modern alias for columnName (matches the plural form every TableDefinition column helper accepts). Pass one or the other — not both.
referenceName string No optional reference name
// 1. Remove a column by specifying its name directly
removeColumn(table="members", columnName="status");

// 2. Remove a reference column using its reference name (removes the <referenceName>id column)
removeColumn(table="posts", referenceName="author");
// Removes the column named "authorid" from the posts table

// 3. Typical use inside a migration's down() method to reverse an addColumn()
function down() {
    removeColumn(table="products", columnName="discountPrice");
}

removeIndex()

Migrator Migration Functions void migration

Remove a database index Only available in a migration CFC

Name Type Required Default Description
table string Yes The table name to perform the index operation on
indexName string Yes the name of the index to remove
// 1. Remove an index by its name
removeIndex(table="members", indexName="members_username");

// 2. Remove a compound index created on multiple columns
// (index was previously added as "orders_customerid_createdat")
removeIndex(table="orders", indexName="orders_customerid_createdat");

// 3. Typical down() migration reversing an addIndex call
component extends="wheels.Migrator" {
    function up() {
        addIndex(table="articles", columnNames="slug", unique=true, indexName="articles_slug");
    }
    function down() {
        removeIndex(table="articles", indexName="articles_slug");
    }
}

removeRecord()

Migrator Migration Functions void migration

Removes existing records from a table Only available in a migration CFC

Name Type Required Default Description
table string Yes The table name to remove the record from
where string No The where clause, i.e id = 123
// 1. Remove all records from a table (use with caution)
removeRecord(table = "sessions");

// 2. Remove a specific record by primary key
removeRecord(table = "roles", where = "id = 1");

// 3. Remove multiple records matching a condition
removeRecord(table = "users", where = "active = 0");

// 4. Use removeRecord in a migration's down() function to reverse an addRecord call
component extends="wheels.migrator.Migration" {
    function up() {
        addRecord(
            table = "settings",
            name = "maintenanceMode",
            value = "false"
        );
    }
    function down() {
        removeRecord(table = "settings", where = "name = 'maintenanceMode'");
    }
}

renameColumn()

Migrator Migration Functions void migration

Renames a table column Only available in a migration CFC

Name Type Required Default Description
table string Yes The table containing the column to rename
columnName string Yes The column name to rename
newColumnName string Yes The new column name
// 1. Rename a column in the users table
renameColumn(table="users", columnName="userName", newColumnName="username");

// 2. Rename a column as part of a migration's up() and down() methods
component extends="wheels.migrator.Migration" hint="Rename fullName to displayName in profiles" {
    function up() {
        renameColumn(table="profiles", columnName="fullName", newColumnName="displayName");
    }

    function down() {
        renameColumn(table="profiles", columnName="displayName", newColumnName="fullName");
    }
}

renameSystemTables()

Migrator General Functions struct migrator

F15 Phase 2: rename legacy c_o_r_e_* system tables to wheels_*. Public API for the wheels migrate rename-system-tables CLI command. Reads the current schema, generates per-adapter rename SQL, and (unless dryRun is true) executes it inside a transaction. After a successful rename, updates application.wheels.{levelsTableName, migratorTableName} to the new names so the running app picks them up without a restart. Result struct: - success: boolean - renamed: array of "old -> new" strings (empty if no-op) - skipped: human message when there's nothing to do - errors: array of error messages (when success=false) - sql: array of SQL statements that would run / did run Refuses to run (returns success=false) when both c_o_r_e_* AND wheels_* versions of either table coexist — that's a partial- rename state which warrants manual cleanup, not silent destruction.

Name Type Required Default Description
dryRun boolean No false When true, returns the SQL that would run without executing.
// 1. Rename legacy c_o_r_e_* tables to wheels_* in one step
result = application.wheels.migrator.renameSystemTables();
// result.success  -> true
// result.renamed  -> ["c_o_r_e_levels -> wheels_levels", "c_o_r_e_migrator_versions -> wheels_migrator_versions"]
// result.sql      -> ["ALTER TABLE c_o_r_e_migrator_versions RENAME TO wheels_migrator_versions", "ALTER TABLE c_o_r_e_levels RENAME TO wheels_levels"]
// result.skipped  -> ""
// result.errors   -> []

// 2. Dry-run: preview the SQL without executing any changes
result = application.wheels.migrator.renameSystemTables(dryRun=true);
// result.success  -> true
// result.renamed  -> []   (nothing executed)
// result.sql      -> ["ALTER TABLE c_o_r_e_migrator_versions RENAME TO wheels_migrator_versions", "ALTER TABLE c_o_r_e_levels RENAME TO wheels_levels"]

// 3. Handle all possible outcomes after running the rename
result = application.wheels.migrator.renameSystemTables();
if (!result.success) {
    // Partial-rename conflict or execution error
    writeOutput("Rename failed: " & arrayToList(result.errors, "; "));
} else if (len(result.skipped)) {
    // Tables were already on wheels_* names (or no legacy tables found)
    writeOutput(result.skipped);
} else {
    writeOutput("Renamed: " & arrayToList(result.renamed, ", "));
}

renameTable()

Migrator Migration Functions void migration

Renames a table Only available in a migration CFC

Name Type Required Default Description
oldName string Yes Name the old table
newName string Yes New name for the table
// 1. Rename a table from its old name to a new name
renameTable(oldName="blogPosts", newName="posts");

// 2. Rename a table as part of a migration up/down pair
component extends="wheels.Migrator" {

    function up() {
        renameTable(oldName="members", newName="users");
    }

    function down() {
        renameTable(oldName="users", newName="members");
    }

}

renderNothing()

Controller Rendering Functions void controller

Instructs the controller to render an empty string when it's finished processing the action. This is very similar to calling cfabort with the advantage that any after filters you have set on the action will still be run.

Name Type Required Default Description
status string No [runtime expression] Force request to return with specific HTTP status code.
// 1. Render a blank response (useful for AJAX fire-and-forget actions)
renderNothing();

// 2. Render a blank response with a specific HTTP status code (e.g., 204 No Content)
renderNothing(status=204);

// 3. Use renderNothing() instead of cfabort so that after-filters still run
// In a controller action:
function markAsRead() {
    post = model("Post").findByKey(params.key);
    post.update(read=true);
    // After-filters (e.g. logging) will still execute, unlike cfabort
    renderNothing();
}

renderPartial()

Controller Rendering Functions any controller

Instructs the controller to render a partial when it's finished processing the action.

Name Type Required Default Description
partial string Yes The name of the partial file to be used. Prefix with a leading slash (/) if you need to build a path from the root views folder. Do not include the partial filename's underscore and file extension.
cache any No Number of minutes to cache the content for.
layout string No The layout to wrap the content in. Prefix with a leading slash (/) if you need to build a path from the root views folder. Pass false to not load a layout at all.
returnAs string No Set to string to return the result instead of automatically sending it to the client.
dataFunction any No true Name of a controller function to load data from.
status string No [runtime expression] Force request to return with specific HTTP status code.
// 1. Render the partial `_comment.cfm` located in the current controller's view folder
renderPartial("comment");

// 2. Render the partial at `app/views/shared/_comment.cfm` using an absolute path
renderPartial("/shared/comment");

// 3. Return the rendered partial as a string instead of sending it to the client
commentHtml = renderPartial(partial="comment", returnAs="string");

// 4. Render a shared partial wrapped in a layout and cache it for 5 minutes
renderPartial(partial="/shared/sidebar", layout="/layouts/sidebar", cache=5);

// 5. Render a partial using a named data-loading function to supply variables
//    (the controller must have a private function named `comment` returning a struct)
renderPartial(partial="comment", dataFunction="comment");

// 6. Render a partial and force a specific HTTP status code (e.g. for AJAX responses)
renderPartial(partial="/shared/error", status=422);

renderSSE()

void controller

Render a single SSE event as the controller response. This sets appropriate headers and formats the response as an SSE event. The client should use EventSource to connect and will receive this single event.

Name Type Required Default Description
data string Yes The event data to send (string). Will be sent as-is.
event string No Optional event type name. Client can listen for specific event types.
id string No Optional event ID. Client sends Last-Event-ID header on reconnect.
retry numeric No 0 Optional reconnection time in milliseconds. Tells client how long to wait before reconnecting.

renderText()

Controller Rendering Functions void controller

Instructs the controller to render specified text when it's finished processing the action.

Name Type Required Default Description
text string No The text to render.
status any No [runtime expression] Force request to return with specific HTTP status code.
// 1. Render a simple text response to the client
renderText("Done!");

// 2. Render serialized JSON data to the client
products = model("Product").findAll();
renderText(serializeJSON(products));

// 3. Render a plain-text response with a custom HTTP status code
renderText(text="Not authorized", status=401);

renderView()

Controller Rendering Functions any controller

Instructs the controller which view template and layout to render when it's finished processing the action. Note that when passing values for controller and / or action, this function does not execute the actual action but rather just loads the corresponding view template.

Name Type Required Default Description
controller string No [runtime expression] Controller to include the view page for.
action string No [runtime expression] Action to include the view page for.
template string No A specific template to render. Prefix with a leading slash (/) if you need to build a path from the root views folder.
layout any No The layout to wrap the content in. Prefix with a leading slash (/) if you need to build a path from the root views folder. Pass false to not load a layout at all.
cache any No Number of minutes to cache the content for.
returnAs string No Set to string to return the result instead of automatically sending it to the client.
hideDebugInformation boolean No false Set to true to hide the debug information at the end of the output. This is useful, for example, when you're testing XML output in an environment where the global setting for showDebugInformation is true.
status string No [runtime expression] Force request to return with specific HTTP status code.
// 1. Render the view template for a different action within the same controller.
renderView(action="edit");

// 2. Render the view template for a different action within a different controller.
renderView(controller="blog", action="new");

// 3. Render a specific template using an absolute path from the `views` folder.
renderView(template="/blog/new");

// 4. Render without a layout and cache the output for 60 minutes.
renderView(layout=false, cache=60);

// 5. Load a layout from a non-default folder within `views`.
renderView(layout="/layouts/blog");

// 6. Return the rendered output as a string instead of sending it to the client.
myView = renderView(returnAs="string");

// 7. Render with a specific HTTP status code (useful for error pages).
renderView(action="notFound", status=404);

// 8. Render XML output and suppress debug information even when `showDebugInformation` is globally enabled.
renderView(template="/reports/summary", layout=false, hideDebugInformation=true);

renderWith()

Controller Rendering Functions any controller

Instructs the controller to render the data passed in to the format that is requested. If the format requested is json or xml, Wheels will transform the data into that format automatically. For other formats (or to override the automatic formatting), you can also create a view template in this format: nameofaction.xml.cfm, nameofaction.json.cfm, nameofaction.pdf.cfm, etc. Per-action format restrictions set with onlyProvides() are enforced here (since 4.0.4): when the requested format is not acceptable for the action, renderWith() falls back to rendering the html view — even when html itself is not in the onlyProvides() list.

Name Type Required Default Description
data any Yes Data to format and render.
controller string No [runtime expression] Controller to include the view page for.
action string No [runtime expression] Action to include the view page for.
template string No A specific template to render. Prefix with a leading slash (/) if you need to build a path from the root views folder.
layout any No The layout to wrap the content in. Prefix with a leading slash (/) if you need to build a path from the root views folder. Pass false to not load a layout at all.
cache any No Number of minutes to cache the content for.
returnAs string No Set to string to return the result instead of automatically sending it to the client.
hideDebugInformation boolean No false Set to true to hide the debug information at the end of the output. This is useful, for example, when you're testing XML output in an environment where the global setting for showDebugInformation is true.
status string No [runtime expression] Force request to return with specific HTTP status code.
// 1. Render a query using the format defined in the controller's `config()` function.
// Wheels automatically serializes to JSON or XML when those formats are requested.
products = model("Product").findAll();
renderWith(products);

// 2. Return a JSON error payload with a specific HTTP status code.
msg = {
	"status": "Error",
	"message": "Not Authenticated"
};
renderWith(data=msg, status=403);

// 3. Render a struct as JSON and return the result as a string instead of sending it to the client.
payload = {"id": 1, "name": "Alice"};
jsonString = renderWith(data=payload, returnAs="string");

// 4. Render with a custom XML template for the current action
// (looks for a view file named `show.xml.cfm` in the current controller's views folder).
user = model("User").findByKey(params.key);
renderWith(data=user, layout=false, hideDebugInformation=true);

// 5. Render data using a specific template from outside the current controller's views folder.
report = model("Order").findAll(select="id,total,createdAt");
renderWith(data=report, template="/reports/summary", layout=false);

resetCycle()

View Helpers Miscellaneous Functions void controller

Resets a cycle so that it starts from the first list value the next time it is called.

Name Type Required Default Description
name string No default The name of the cycle to reset.
// 1. Reset the default cycle between grouped query sections
<cfoutput query="posts" group="categoryId">
	resetCycle();
	<cfoutput>
		rowClass = cycle(values="even,odd");
		writeOutput(rowClass & ": " & posts.title);
	</cfoutput>
</cfoutput>

// 2. Reset a named cycle so it starts over for each department group
<cfoutput query="employees" group="departmentId">
	resetCycle("position");
	<cfoutput>
		rank = cycle(values="manager,specialist,intern", name="position");
		writeOutput(employees.lastName & " - " & rank);
	</cfoutput>
</cfoutput>

// 3. Reset all cycles by name after rendering a section
resetCycle("row");
resetCycle("highlight");

resource()

Configuration Routing struct mapper

Create a group of routes that exposes actions for manipulating a singular resource. A singular resource exposes URL patterns for the entire CRUD lifecycle of a single entity (show, new, create, edit, update, and delete) without exposing a primary key in the URL. Usually this type of resource represents a singleton entity tied to the session, application, or another resource (perhaps nested within another resource). If you need to generate routes for manipulating a collection of resources with a primary key in the URL, see the resources mapper method.

Name Type Required Default Description
name string Yes Camel-case name of resource to reference when build links and form actions. This is typically a singular word (e.g., profile).
nested boolean No false Whether or not additional calls will be nested within this resource.
path string No [runtime expression] Override URL path representing this resource. Default is a dasherized version of name (e.g., blogPost generates a path of blog-post).
controller string No Override name of the controller used by resource. This defaults to a pluralized version of name.
singular string No Override singularize() result in plural resources.
plural string No Override pluralize() result in singular resource.
only string No Limits the list of RESTful routes to generate. Can include show, new, create, edit, update, and delete.
except string No Excludes RESTful routes to generate, taking priority over the only argument. Can include show, new, create, edit, update, and delete.
shallow boolean No Turn on shallow resources.
shallowPath string No Shallow path prefix.
shallowName string No Shallow name prefix.
constraints struct No Variable patterns to use for matching.
callback any No
binding any No
mapFormat boolean No [runtime expression] Whether or not to add an optional .[format] pattern to the end of the generated routes. This is useful for providing formats via URL like json, xml, pdf, etc.
<cfscript>

mapper()
    // 1. Minimal singular resource — generates show, new, create, edit, update, delete routes
    .resource("checkout")

    // 2. Point to a controller at a custom path (app/controllers/sessions/Auth.cfc)
    .resource(name="auth", controller="sessions/auth")

    // 3. Limit generated routes with the `only` argument
    .resource(name="profile", only="show,edit,update")

    // 4. Exclude specific routes with the `except` argument
    .resource(name="cart", except="new,create")

    // 5. Nested singular resource — nest additional routes inside, then close with end()
    .resource(name="preferences", nested=true)
      .get(name="editPassword", to="passwords##edit")
      .patch(name="password", to="passwords##update")
      .resources("notifications")
    .end()

    // 6. Override the URL path (blogPostOptions -> blog-post/options instead of blog-post-options)
    .resource(name="blogPostOptions", path="blog-post/options")
.end();

</cfscript>

resources()

Configuration Routing struct mapper

Create a group of routes that exposes actions for manipulating a collection of resources. A plural resource exposes URL patterns for the entire CRUD lifecycle (index, show, new, create, edit, update, delete), exposing a primary key in the URL for showing, editing, updating, and deleting records. If you need to generate routes for manipulating a singular resource without a primary key, see the resource mapper method.

Name Type Required Default Description
name string Yes Camel-case name of resource to reference when build links and form actions. This is typically a plural word (e.g., posts).
nested boolean No false Whether or not additional calls will be nested within this resource.
path string No [runtime expression] Override URL path representing this resource. Default is a dasherized version of name (e.g., blogPosts generates a path of blog-posts).
controller string No Override name of the controller used by resource. This defaults to the value provided for name.
singular string No Override singularize() result in plural resources.
plural string No Override pluralize() result in singular resource.
only string No Limits the list of RESTful routes to generate. Can include index, show, new, create, edit, update, and delete.
except string No Excludes RESTful routes to generate, taking priority over the only argument. Can include index, show, new, create, edit, update, and delete.
shallow boolean No Turn on shallow resources.
shallowPath string No Shallow path prefix.
shallowName string No Shallow name prefix.
constraints struct No Variable patterns to use for matching.
callback any No
binding any No
mapFormat boolean No [runtime expression] Whether or not to add an optional .[format] pattern to the end of the generated routes. This is useful for providing formats via URL like json, xml, pdf, etc.
<cfscript>

mapper()
    // 1. Basic CRUD resource — generates index, show, new, create, edit, update, delete routes
    .resources("admins")

    // 2. Point authors URL to controller at `app/controllers/Users.cfc`
    .resources(name="authors", controller="users")

    // 3. Limit routes to a specific set with the `only` argument
    .resources(name="products", only="index,show,edit,update")

    // 4. Exclude specific routes using the `except` argument
    .resources(name="orders", except="delete")

    // 5. Nested resources — child routes receive parent key in URL (e.g. /stories/1/heroes)
    .resources(name="stories", nested=true)
        .resources("heroes")
        .resources("villains")
    .end()

    // 6. Override the URL path (e.g. /blog-posts/options instead of /blog-posts-options)
    .resources(name="blogPostsOptions", path="blog-posts/options")

    // 7. Shallow nesting — member routes (show, edit, update, delete) drop the parent prefix
    .resources(name="posts", nested=true, shallow=true)
        .resources("comments")
    .end()

    // 8. Constrain URL parameters to a specific pattern (e.g. numeric IDs only)
    .resources(name="photos", constraints={key="[0-9]+"})

    // 9. Override the singularized form when auto-detection is wrong
    .resources(name="people", singular="person")
.end();

</cfscript>

response()

Controller Rendering Functions string controller

Returns content that Wheels will send to the client in response to the request.

// 1. Get the current response content (empty string if nothing has been rendered yet)
content = response();

// 2. Use in a controller test to verify rendered output
// (Wheels populates the response after renderView, renderText, or renderPartial runs)
renderText("Hello, world!");
assert("response() eq 'Hello, world!'");

// 3. Inspect and modify the response before it is sent to the client
currentContent = response();
if (FindNoCase("<!-- debug -->", currentContent)) {
    setResponse(Replace(currentContent, "<!-- debug -->", "", "all"));
}

root()

Configuration Routing struct mapper

Create a route that matches the root of its current context. This mapper can be used for the application's web root (or home page), or it can generate a route for the root of a namespace or other path scoping mapper. The route only responds to the GET verb unless you explicitly pass a method (or methods) argument.

Name Type Required Default Description
to string No Set controller##action combination to map the route to. You may use either this argument or a combination of controller and action.
mapFormat boolean No Set to true to include the format (e.g. .json) in the route.
<cfscript>

// 1. Map the application's web root (home page) to a specific controller action
mapper()
    // Map "/" to the `index` action of the `home` controller
    .root(to="home##index")
.end();

// 2. Map the root of a namespace scope using separate controller and action arguments
mapper()
    .namespace("admin")
        // Map "/admin/" to the `dashboard` action of the `admin` controller
        .root(controller="admin", action="dashboard")
    .end()
.end();

// 3. Map the root with format matching enabled so ".json" etc. are captured
mapper()
    .namespace("api")
        // Map "/api/" and "/api/.json" (etc.) to the `apis` controller's `index` action
        .root(to="apis##index", mapFormat=true)
    .end()
.end();

</cfscript>

save()

Model Class CRUD Functions boolean model

Saves the object if it passes validation and callbacks. Returns true if the object was saved successfully to the database, false if not.

Name Type Required Default Description
parameterize any No true Set to true to use cfqueryparam on all columns, or pass in a list of property names to use cfqueryparam on those only.
reload boolean No false Set to true to force Wheels to query the database even though an identical query for this model may have been run in the same request. (The default in Wheels is to get the second query from the model's request-level cache.)
validate boolean No true Set to false to skip validations for this operation.
transaction string No [runtime expression] Set this to commit to update the database, rollback to run all the database queries but not commit them, or none to skip transaction handling altogether.
callbacks boolean No true Set to false to disable callbacks for this method.
// 1. Save a user object to the database (automatically does INSERT or UPDATE depending on whether the record is new)
user.save();

// 2. Use save() in a conditional to handle success and failure
if (user.save()) {
	flashInsert(notice="The user was saved successfully!");
	redirectTo(action="edit");
} else {
	flashInsert(alert="Please correct the errors below.");
	renderView(action="edit");
}

// 3. Save without running validations (useful for administrative operations or data migrations)
user.save(validate=false);

// 4. Save using cfqueryparam only on specific properties (pass a list of property names)
user.save(parameterize="firstName,lastName,email");

// 5. Save and force a database reload of the object afterward (instead of using the request-level cache)
user.save(reload=true);

scope()

Model Configuration Scope Functions void model

Defines a named query scope that can be chained onto finders. Scopes allow you to define reusable query fragments in the model config and compose them together.

Name Type Required Default Description
name string Yes The name of the scope. This becomes a callable method on the model (e.g. model("User").active()).
where string No A WHERE clause fragment to apply when this scope is used.
order string No An ORDER BY clause fragment to apply when this scope is used.
select string No A SELECT clause override to apply when this scope is used.
include string No Associations to include when this scope is used.
maxRows numeric No 0 Maximum number of records to return when this scope is used.
handler string No The name of a method on this model that returns a struct of query arguments. Use for dynamic scopes that accept parameters. The method receives any arguments passed to the scope call.

scope()

Configuration Routing struct mapper

Set any number of parameters to be inherited by mappers called within this matcher's block. For example, set a package or URL path to be used by all child routes.

Name Type Required Default Description
name string No Name to prepend to child route names for use when building links, forms, and other URLs.
path string No Path to prefix to all child routes.
package string No Package namespace to append to controllers.
controller string No Controller to use for routes.
shallow boolean No Turn on shallow resources to eliminate routing added before this one.
shallowPath string No Shallow path prefix.
shallowName string No Shallow name prefix.
constraints struct No Variable patterns to use for matching.
middleware any No
binding any No
callback any No A callback function to define nested routes within this scope. If provided, the scope is automatically closed when the callback completes.
<cfscript>

mapper()
    // 1. Scope routes to a specific controller.
    // All routes inside will use the `freeForAll` controller.
    .scope(controller="freeForAll")
        .get(name="bananas", action="bananas")
        .root(action="index")
    .end()

    // 2. Scope routes to a package (subfolder) without affecting the URL.
    // All routes' controllers inside will be inside the `public` package/subfolder.
    .scope(package="public")
        .resource(name="search", only="show,create")
    .end()

    // 3. Scope routes under a URL path prefix.
    // All routes inside will be prepended with a URL path of `phones/`.
    .scope(path="phones")
        .get(name="newest", to="phones##newest")
        .get(name="sortOfNew", to="phones##sortOfNew")
    .end()

    // 4. Scope routes with both a name prefix and URL path prefix.
    // Generates named routes like `adminUsers` and `adminPosts`.
    .scope(name="admin", path="admin")
        .resources(name="users")
        .resources(name="posts")
    .end()

    // 5. Scope routes with URL variable constraints applied to all children.
    .scope(constraints={id="[0-9]+"})
        .get(name="userProfile", to="users##profile")
        .resources(name="orders")
    .end()
.end();

</cfscript>

scopeInfo()

Model Class Miscellaneous Functions struct model

Returns a struct containing all named scope definitions for this model. Each key is the scope name, and the value is a struct with query fragment keys like where, order, select, include.

// 1. Inspect all named scopes defined on a model
info = model("Article").scopeInfo();
// info -> {
//   active:    { where: "status = 'active'" },
//   recent:    { where: "publishedAt > ?", order: "publishedAt DESC" },
//   published: { where: "status = 'published'", order: "publishedAt DESC" }
// }

// 2. Check whether a specific scope is defined before using it
info = model("User").scopeInfo();
if (structKeyExists(info, "admins")) {
    admins = model("User").admins().findAll();
}

// 3. List all scope names registered on a model
info = model("Post").scopeInfo();
writeOutput(structKeyList(info));
// -> "featured,archived,byDate"

searchField()

View Helpers Form Object Functions string controller

Builds and returns a string containing a search field form control based on the supplied objectName and property. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
objectName any Yes The variable name of the object to build the form control for.
property string Yes The name of the property to use in the form control.
association string No The name of the association that the property is located on. Used for building nested forms that work with nested properties. If you are building a form with deep nesting, simply pass in a list to the nested object, and Wheels will figure it out.
position string No The position used when referencing a hasMany relationship in the association argument. Used for building nested forms that work with nested properties. If you are building a form with deep nestings, simply pass in a list of positions, and Wheels will figure it out.
label string No useDefaultLabel The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
errorElement string No span HTML tag to wrap the form control with when the object contains errors.
errorClass string No field-with-errors The class name of the HTML tag that wraps the form control when there are errors.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic search field bound to a model object
#searchField(objectName="searchForm", property="query")#

// 2. Search field with a custom label and placeholder attribute
#searchField(objectName="searchForm", property="query", label="Search", placeholder="Enter keywords...")#

// 3. Search field with label placement after the input and a CSS class
#searchField(objectName="searchForm", property="query", label="Search", labelPlacement="after", class="search-input")#

searchFieldTag()

View Helpers Form Tag Functions string controller

Builds and returns a string containing a search field form control based on the supplied name. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
name string Yes Name to populate in tag's name attribute.
value string No Value to populate in tag's value attribute.
label string No The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic search field with a label and pre-populated value
#searchFieldTag(name="q", value=params.q, label="Search")#

// 2. Search field with a placeholder and CSS class (extra HTML attributes are passed through)
#searchFieldTag(name="keywords", label="Keywords", placeholder="Enter keywords...", class="search-input")#

// 3. Search field without a label, value carried from params
#searchFieldTag(name="q", value=params.q)#

secondSelectTag()

View Helpers Form Tag Functions string controller

Builds and returns a string containing one select form control for the seconds of a minute based on the supplied name.

Name Type Required Default Description
name string Yes Name to populate in tag's name attribute.
selected string No The second that should be selected initially.
secondStep numeric No 1 Pass in 10 to only show seconds 10, 20, 30, etc.
includeBlank any No false Whether to include a blank option in the select form control. Pass true to include a blank line or a string that should represent what display text should appear for the empty value (for example, "- Select One -").
label string No The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic usage — render a seconds select for a countdown form
#secondSelectTag(name="secondsToLaunch", selected=params.secondsToLaunch)#

// 2. Only show 15-second intervals (0, 15, 30, 45)
#secondSelectTag(name="secondsToLaunch", selected=params.secondsToLaunch, secondStep=15)#

// 3. Include a blank option and wrap with a label
#secondSelectTag(name="second", selected=params.second, includeBlank=true, label="Second")#

sectionActive()

boolean controller

Une section du site est-elle active ? Valeur par defaut VRAIE : si l'API ne repond pas, on montre le site plutot que de le vider. Un reglage manquant ne doit pas faire disparaitre le contenu.

Name Type Required Default Description
code string Yes

select()

View Helpers Form Object Functions string controller

Builds and returns a string containing a select form control based on the supplied objectName and property. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
objectName any Yes The variable name of the object to build the form control for.
property string Yes The name of the property to use in the form control.
association string No The name of the association that the property is located on. Used for building nested forms that work with nested properties. If you are building a form with deep nesting, simply pass in a list to the nested object, and Wheels will figure it out.
position string No The position used when referencing a hasMany relationship in the association argument. Used for building nested forms that work with nested properties. If you are building a form with deep nestings, simply pass in a list of positions, and Wheels will figure it out.
options any No A collection to populate the select form control with. Can be a query recordSet or an array of objects.
includeBlank any No false Whether to include a blank option in the select form control. Pass true to include a blank line or a string that should represent what display text should appear for the empty value (for example, "- Select One -").
valueField string No The column or property to use for the value of each list element. Used only when a query or array of objects has been supplied in the options argument. Required when specifying textField
textField string No The column or property to use for the value of each list element that the end user will see. Used only when a query or array of objects has been supplied in the options argument. Required when specifying valueField
label string No useDefaultLabel The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
errorElement string No span HTML tag to wrap the form control with when the object contains errors.
errorClass string No field-with-errors The class name of the HTML tag that wraps the form control when there are errors.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic select field bound to a model object property
// Controller
authors = model("Author").findAll(order="lastName");
// View
#select(objectName="book", property="authorId", options=authors)#

// 2. Override which query columns to use for option values and display text
// Controller
authors = model("Author").findAll(order="lastName");
// View
#select(objectName="book", property="authorId", options=authors, valueField="id", textField="fullName")#

// 3. Include a blank/placeholder option at the top of the list
#select(objectName="order", property="statusId", options=statuses, includeBlank="-- Select a Status --")#

// 4. Populate options from a simple list or array instead of a query
#select(objectName="profile", property="country", options="Canada,Mexico,United States")#

// 5. Allow multiple selections (multi-select box)
#select(objectName="post", property="tagIds", options=tags, multiple=true, label="Tags")#

// 6. Nested form — select within a hasMany association loop
// Controller
shipment = model("Shipment").findByKey(params.key, include="orders");
statuses = model("Status").findAll(order="name");
// View
<cfloop from="1" to="#ArrayLen(shipment.orders)#" index="i">
    #select(
        label        = "Order ##shipment.orders[i].orderNumber##",
        objectName   = "shipment",
        association  = "orders",
        position     = i,
        property     = "statusId",
        options      = statuses,
        includeBlank = true
    )#
</cfloop>

selectTag()

View Helpers Form Tag Functions string controller

Builds and returns a string containing a select form control based on the supplied name and options. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
name string Yes Name to populate in tag's name attribute.
options any Yes A collection to populate the select form control with. Can be a query recordSet or an array of objects.
selected string No Value of option that should be selected by default.
includeBlank any No false Whether to include a blank option in the select form control. Pass true to include a blank line or a string that should represent what display text should appear for the empty value (for example, "- Select One -").
multiple boolean No false Whether to allow multiple selection of options in the select form control.
valueField string No The column or property to use for the value of each list element. Used only when a query or array of objects has been supplied in the options argument. Required when specifying textField
textField string No The column or property to use for the value of each list element that the end user will see. Used only when a query or array of objects has been supplied in the options argument. Required when specifying valueField
label string No The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic usage with a simple list of options
#selectTag(name="color", options="Red,Green,Blue")#

// 2. Use a query as the options source, specifying which columns map to value and display text
cities = model("City").findAll(order="name");
#selectTag(name="cityId", options=cities, valueField="id", textField="name")#

// 3. Pre-select a value and include a blank "please choose" option
#selectTag(name="cityId", options=cities, valueField="id", textField="name", selected=params.cityId, includeBlank="- Select a City -")#

// 4. Allow multiple selections
#selectTag(name="tagIds", options=model("Tag").findAll(order="name"), valueField="id", textField="name", multiple=true)#

sendEmail()

Controller Miscellaneous Functions any controller

Sends an email using a template and an optional layout to wrap it in. Besides the Wheels-specific arguments documented here, you can also pass in any argument that is accepted by the cfmail tag as well as your own arguments to be used by the view. Note that only arguments whose names match a known cfmail attribute are passed through to cfmail; every other argument is made available to the email view as a variable instead.

Name Type Required Default Description
template string No The path to the email template or two paths if you want to send a multipart email (a maximum of two templates, one text and one html version, is supported). if the detectMultipart argument is false, the template for the text version should be the first one in the list. This argument is also aliased as templates.
from string Yes Email address to send from.
to string Yes List of email addresses to send the email to.
subject string Yes The subject line of the email.
layout any No false Layout(s) to wrap the email template in. This argument is also aliased as layouts.
file string No A list of the names of the files to attach to the email. This will reference files stored in the files folder (or a path relative to it). This argument is also aliased as files.
detectMultipart boolean No true When set to true and multiple values are provided for the template argument, Wheels will detect which of the templates is text and which one is HTML (by counting the < characters).
deliver boolean No true When set to false, the email will not be sent.
writeToFile string No The file to which the email contents will be written
// 1. Send a welcome email to a new member, passing custom variables to the template
newMember = model("Member").findByKey(params.member.id);
sendEmail(
	from="welcome@example.com",
	to=newMember.email,
	subject="Thank You for Becoming a Member",
	template="welcomeEmail",
	recipientName=newMember.name,
	startDate=newMember.startDate
);

// 2. Send a multipart email (text + HTML) using two templates
sendEmail(
	from="news@example.com",
	to=params.subscriber.email,
	subject="Your Weekly Newsletter",
	template="newsletterText,newsletterHtml",
	layout=false,
	issueDate=Now()
);

// 3. Send an email with a file attachment and suppress actual delivery (e.g. during testing)
sendEmail(
	from="billing@example.com",
	to=params.customer.email,
	subject="Your Invoice",
	template="invoiceEmail",
	file="invoice_2024.pdf",
	deliver=false
);

sendFile()

Controller Miscellaneous Functions any controller

Sends a file to the user (from the files folder or a path relative to it by default).

Name Type Required Default Description
file string Yes The file to send to the user. Values containing the .. character sequence anywhere (even as part of a legitimate file name) are rejected to prevent path traversal.
name string No The file name to show in the browser download dialog box.
type string No The HTTP content type to deliver the file as.
disposition string No attachment Set to inline to have the browser handle the opening of the file (possibly inline in the browser) or set to attachment to force a download dialog box.
directory string No Directory outside of the web root where the file exists. Must be a full path. Values containing the .. character sequence are rejected to prevent path traversal.
deleteFile boolean No false Pass in true to delete the file on the server after sending it.
deliver boolean No true When set to false, the file will not be sent to the browser (used for testing).
// 1. Send a PDF file to the user from the default files folder
sendFile(file="wheels_tutorial_20081028_J657D6HX.pdf");

// 2. Send the same file but give the user a friendlier name in the browser download dialog
sendFile(file="wheels_tutorial_20081028_J657D6HX.pdf", name="Tutorial.pdf");

// 3. Display the file inline in the browser instead of forcing a download dialog
sendFile(file="report.pdf", disposition="inline");

// 4. Send a file with an explicit MIME type
sendFile(file="export.csv", type="text/csv", name="data-export.csv");

// 5. Send a file located outside of the web root using an absolute directory path
sendFile(file="invoice_2024_001.pdf", directory="/var/app/private/invoices");

// 6. Send a file and delete it from the server after delivery (e.g., a temporary export)
sendFile(file="temp_export_J657D6HX.csv", name="export.csv", deleteFile=true);

// 7. Send a file stored in the RAM virtual file system
sendFile(file="ram://generated_report.pdf", name="report.pdf");

sendSSEComment()

void controller

Send an SSE comment (keep-alive ping) through a streaming writer.

Name Type Required Default Description
writer any Yes The writer object returned by initSSEStream().
comment string No ping Optional comment text.

sendSSEEvent()

void controller

Send an SSE event through a streaming writer obtained from initSSEStream().

Name Type Required Default Description
writer any Yes The writer object returned by initSSEStream().
data string Yes The event data to send.
event string No Optional event type name.
id string No Optional event ID.
retry numeric No 0 Optional reconnection time in milliseconds.

service()

any controller model mapper migrator migration tabledefinition

Resout un composant de la couche de services du front. Meme principe que dans l'API, en plus simple : le front n'a aucun modele, donc rien a injecter que la configuration. Un service ne connait ni params, ni les entetes. Cache de portee REQUETE : le contrat (§8) interdit de compter sur un etat en memoire entre requetes.

Name Type Required Default Description
name string Yes
// 1. Resolve a registered service and call a method on it
mailer = service("MailerService");
mailer.send(to="user@example.com", subject="Welcome!");

// 2. Resolve a payment gateway service and process a charge
gateway = service("PaymentGateway");
result = gateway.charge(amount=params.amount, token=params.stripeToken);

// 3. Use a service in a model callback to send a notification
component extends="Model" {
    function config() {
        afterCreate(method="notifyAdmin");
    }

    private function notifyAdmin() {
        notifier = service("NotificationService");
        notifier.notify(event="userCreated", userId=this.id);
    }
}

set()

Configuration Miscellaneous Functions void controller model mapper migrator migration tabledefinition

Use to configure a global setting or set a default for a function.

// 1. Set the `URLRewriting` global setting to `Partial`.
set(URLRewriting="Partial");

// 2. Set default argument values for the `buttonTo` view helper.
// This pattern works for most Wheels helper functions and their arguments.
set(functionName="buttonTo", onlyPath=true, host="", protocol="", port=0, text="", confirm="", image="", disable="");

// 3. Set default values for the `textField` form helper to control label placement and wrapping markup.
set(functionName="textField", labelPlacement="before", prependToLabel="<div>", append="</div>", appendToLabel="<br>");

// 4. Apply the same defaults to multiple helper functions at once by passing a comma-delimited list to `functionName`.
set(functionName="textField,passwordField,textArea", labelPlacement="before");

setFilterChain()

Controller Configuration Functions void controller

Use this function if you need a more low level way of setting the entire filter chain for a controller.

Name Type Required Default Description
chain array Yes An array of structs, each of which represent an argumentCollection that get passed to the filters function. This should represent the entire filter chain that you want to use for this controller.
// 1. Set the entire filter chain directly using an array of structs
setFilterChain([
	{through="restrictAccess"},
	{through="isLoggedIn, checkIPAddress", except="home, login"},
	{type="after", through="logConversion", only="thankYou"}
]);

// 2. Replace an inherited filter chain in a child controller by starting fresh
// In app/controllers/Admin.cfc config():
parentChain = filterChain();
// Modify parentChain as needed, then reassign it wholesale
setFilterChain([
	{through="requireAdmin"},
	{through="loadCurrentUser", except="login"},
	{type="after", through="auditAction"}
]);

// 3. Conditionally swap the filter chain based on application mode
if (get("environment") == "testing") {
	setFilterChain([
		{through="stubAuthentication"}
	]);
} else {
	setFilterChain([
		{through="requireSSL"},
		{through="authenticate"},
		{type="after", through="trackPageView"}
	]);
}

setFlashStorage()

Controller Flash Functions void controller

Dynamically sets flashStorage during request lifecycle.

Name Type Required Default Description
storage string No session Accepts "session" or "cookie"
setGlobally boolean No false If true, updates both app-level and controller-level flashStorage
// 1. Switch flash storage to cookie for the current request only
setFlashStorage(storage="cookie");
flashInsert(notice="Switching to cookie-based flash.");

// 2. Switch flash storage to session (the default) for the current request only
setFlashStorage(storage="session");

// 3. Update flash storage globally so all subsequent requests also use cookie storage
setFlashStorage(storage="cookie", setGlobally=true);

setPagination()

Controller Pagination Functions void controller model mapper migrator migration tabledefinition

Allows you to set a pagination handle for a custom query so you can perform pagination on it in your view with paginationLinks.

Name Type Required Default Description
totalRecords numeric Yes Total count of records that should be represented by the paginated links.
currentPage numeric No 1 Page number that should be represented by the data being fetched and the paginated links.
perPage numeric No 25 Number of records that should be represented on each page of data.
handle string No query Name of handle to reference in paginationLinks.
// 1. Basic usage: paginate a custom query inside a model method, letting the CFML engine handle pagination
// In app/models/User.cfc
function searchByName(required string name, numeric page = 1, numeric perPage = 25) {
	local.allMatches = QueryExecute(
		"SELECT * FROM users WHERE firstName LIKE :name ORDER BY lastName",
		{ name = { value = "%" & arguments.name & "%", cfsqltype = "cf_sql_varchar" } },
		{ datasource = get("dataSourceName") }
	);
	setPagination(
		totalRecords = local.allMatches.recordCount,
		currentPage  = arguments.page,
		perPage      = arguments.perPage,
		handle       = "userSearch"
	);
	return local.allMatches;
}

// In app/controllers/Users.cfc
function search() {
	param name="params.page"    default="1";
	param name="params.perPage" default="25";
	searchResults = model("User").searchByName(
		name    = params.q,
		page    = params.page,
		perPage = params.perPage
	);
	paginationData = pagination("userSearch");
}

<!--- In app/views/users/search.cfm --->
<!--- Use startRow / endRow to page through the full query result --->
<ul>
	<cfloop query="searchResults"
	        startRow="#paginationData.startRow#"
	        endRow="#paginationData.endRow#">
		<li>#searchResults.firstName# #searchResults.lastName#</li>
	</cfloop>
</ul>
#paginationLinks(handle="userSearch")#

// 2. Database-level pagination: run a COUNT query and a page-slice query separately
// In app/models/Article.cfc
function pagedResults(numeric page = 1, numeric perPage = 10) {
	local.countQuery = QueryExecute(
		"SELECT COUNT(*) AS total FROM articles WHERE publishedAt IS NOT NULL",
		[],
		{ datasource = get("dataSourceName") }
	);
	local.pageQuery = QueryExecute(
		"SELECT * FROM articles WHERE publishedAt IS NOT NULL ORDER BY publishedAt DESC LIMIT :perPage OFFSET :offset",
		{
			perPage = { value = arguments.perPage, cfsqltype = "cf_sql_integer" },
			offset  = { value = (arguments.page - 1) * arguments.perPage, cfsqltype = "cf_sql_integer" }
		},
		{ datasource = get("dataSourceName") }
	);
	// Use the COUNT result so paginationLinks reflects the total, not just this page
	setPagination(
		totalRecords = local.countQuery.total,
		currentPage  = arguments.page,
		perPage      = arguments.perPage,
		handle       = "articles"
	);
	return local.pageQuery;
}

// In app/controllers/Articles.cfc
function index() {
	param name="params.page"    default="1";
	param name="params.perPage" default="10";
	articles = model("Article").pagedResults(
		page    = params.page,
		perPage = params.perPage
	);
}

<!--- In app/views/articles/index.cfm --->
<ul>
	<cfloop query="articles">
		<li>#articles.title#</li>
	</cfloop>
</ul>
#paginationLinks(handle="articles")#

// 3. Use the default handle name so paginationLinks() needs no handle argument
// In app/models/Product.cfc
function featured(numeric page = 1) {
	local.q = QueryExecute(
		"SELECT * FROM products WHERE featured = 1 ORDER BY name",
		[],
		{ datasource = get("dataSourceName") }
	);
	// Omitting handle defaults it to "query", matching paginationLinks() default
	setPagination(totalRecords = local.q.recordCount, currentPage = arguments.page);
	return local.q;
}

// In app/controllers/Products.cfc
function index() {
	param name="params.page" default="1";
	products     = model("Product").featured(page = params.page);
	pagingData   = pagination(); // uses default handle "query"
}

<!--- In app/views/products/index.cfm --->
<ul>
	<cfloop query="products"
	        startRow="#pagingData.startRow#"
	        endRow="#pagingData.endRow#">
		<li>#products.name#</li>
	</cfloop>
</ul>
#paginationLinks()#

setPrimaryKey()

Model Configuration Miscellaneous Functions void model

Allows you to pass in the name(s) of the property(s) that should be used as the primary key(s). Pass as a list if defining a composite primary key. This function is also aliased as setPrimaryKeys().

Name Type Required Default Description
property string Yes Property (or list of properties) to set as the primary key.
// 1. In `models/User.cfc`, define the primary key as a column called `userID`
//    instead of the Wheels default of `id`.
component extends="Model" {
	function config() {
		setPrimaryKey("userID");
	}
}

// 2. Define a composite primary key for a join model using two columns.
//    `setPrimaryKeys()` is an alias for `setPrimaryKey()` that reads more
//    naturally when multiple properties are involved.
component extends="Model" {
	function config() {
		table("users_roles");
		setPrimaryKeys("userID,roleID");
	}
}

setPrimaryKeys()

Model Configuration Miscellaneous Functions void model

Alias for setPrimaryKey(). Use this for better readability when you're setting multiple properties as the primary key.

Name Type Required Default Description
property string Yes Property (or list of properties) to set as the primary key.
// 1. In `models/Subscription.cfc`, define the primary key as a composite of `customerId` and `publicationId`.
component extends="Model" {
	function config() {
		setPrimaryKeys("customerId,publicationId");
	}
}

// 2. In `models/OrderItem.cfc`, define a composite primary key using three columns.
component extends="Model" {
	function config() {
		setPrimaryKeys("orderId,productId,warehouseId");
	}
}

setProperties()

Model Object Miscellaneous Functions void model

Allows you to set all the properties of an object at once by passing in a structure with keys matching the property names.

Name Type Required Default Description
properties struct No [runtime expression] The properties you want to set on the object (can also be passed in as named arguments).
// 1. Update properties from a form post struct
user = model("User").findByKey(1);
user.setProperties(params.user);

// 2. Pass a struct literal directly to set multiple properties at once
user = model("User").findByKey(1);
user.setProperties({firstName: "Jane", lastName: "Doe", email: "jane@example.com"});
user.save();

// 3. Use named arguments instead of a struct (named args are merged with the properties struct)
user = model("User").findByKey(1);
user.setProperties(firstName="John", lastName="Smith");
user.save();

setResponse()

Controller Rendering Functions void controller

Sets content that Wheels will send to the client in response to the request.

Name Type Required Default Description
content string Yes The content to send to the client.
// 1. Override the response body with a plain string
setResponse("Maintenance mode active. Please try again later.");

// 2. Modify an already-rendered response in an after filter
// (e.g. append a debug comment to every HTML response)
private void function appendDebugComment() {
    current = response();
    setResponse(current & "<!-- rendered at #Now()# -->");
}

// 3. Replace the response with serialized data after a renderView() call
// (useful in tests or custom middleware-style filters)
setResponse(serializeJSON({status: "ok", timestamp: Now()}));

setTableNamePrefix()

Model Configuration Miscellaneous Functions void model

Sets a prefix to prepend to the table name when this model runs SQL queries.

Name Type Required Default Description
prefix string Yes A prefix to prepend to the table name.
// 1. In `models/User.cfc`, prepend `tbl` to the default table name so
//    Wheels queries the `tblusers` table instead of `users`.
function config() {
	setTableNamePrefix("tbl");
}

// 2. Use a schema-style prefix to namespace legacy tables shared across
//    multiple applications on the same database.
// models/Order.cfc
component extends="Model" {
	function config() {
		setTableNamePrefix("legacy_");
		// Wheels will now query `legacy_orders` for this model.
	}
}

setVerificationChain()

Controller Configuration Functions void controller

Use this function if you need a more low level way of setting the entire verification chain for a controller.

Name Type Required Default Description
chain array Yes An array of structs, each of which represent an argumentCollection that get passed to the verifies function. This should represent the entire verification chain that you want to use for this controller.
// 1. Set the entire verification chain directly using an array of structs
setVerificationChain([
	{only="handleForm", post=true},
	{only="edit", get=true, params="userId", paramsTypes="integer"},
	{only="delete", post=true, session="currentUser", handler="accessDenied"}
]);

// 2. Get the existing chain, modify it, and set it back
chain = verificationChain();
ArrayAppend(chain, {only="create,update", post=true});
setVerificationChain(chain);

// 3. Replace the chain built by a parent controller with a stricter one
setVerificationChain([
	{except="index,show", post=true, session="isAdmin", handler="requireAdmin"},
	{only="destroy", post=true}
]);

sharedModel()

Model Configuration Multi-Tenancy void model

Marks this model as shared — it will always use the default application datasource even when a tenant is active. Use this for models like Tenant, Plan, or any lookup table that lives in the central database rather than per-tenant databases.

// 1. Mark the Tenant model as shared so it always reads from the central database
// models/Tenant.cfc
component extends="Model" {
    function config() {
        sharedModel();
    }
}

// 2. Use sharedModel() for lookup tables that live in the central database,
//    not in per-tenant databases
// models/Plan.cfc
component extends="Model" {
    function config() {
        sharedModel();
        // All finder calls on Plan will use the default application datasource
        // regardless of which tenant is currently active.
    }
}

simpleFormat()

View Helpers Miscellaneous Functions string controller

Returns formatted text using HTML break tags (
) and HTML paragraph elements (

) based on the newline characters and carriage returns in the text that is passed in.

Name Type Required Default Description
text string Yes The text to format.
wrap boolean No true Set to true to wrap the result in a paragraph HTML element.
encode boolean No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Format a blog post body — newlines become <br> and blank lines become paragraph breaks
writeOutput(simpleFormat(post.bodyText));
// A single newline becomes <br>
// A blank line (two newlines) becomes </p><p>
// The result is wrapped in <p>...</p> by default

// 2. Demonstrate the HTML output with literal input
text = "I love this post!" & Chr(10) & Chr(10) & "Here's why:" & Chr(10) & "* Short" & Chr(10) & "* Succinct";
writeOutput(simpleFormat(text));
// -> <p>I love this post!</p>
//
//    <p>Here's why:<br>
//    * Short<br>
//    * Succinct</p>

// 3. Skip the wrapping paragraph tag (wrap=false) when you are composing markup yourself
writeOutput("<div>" & simpleFormat(text=post.excerpt, wrap=false) & "</div>");

// 4. Disable XSS encoding when the text is already trusted/pre-encoded HTML
writeOutput(simpleFormat(text=post.bodyText, encode=false));

singularize()

Global Helpers String Functions string controller model mapper migrator migration tabledefinition

Returns the singular form of the passed in word.

Name Type Required Default Description
word string Yes The word to singularize.
// 1. Singularize a regular plural word
singular = singularize("languages");
// singular -> "language"

// 2. Singularize an irregular plural
singular = singularize("children");
// singular -> "child"

// 3. Singularize a camelCased word (only the last part is singularized)
singular = singularize("blogPosts");
// singular -> "blogPost"

startFormTag()

View Helpers General Form Functions string controller

Builds and returns a string containing the opening form tag. The form's action will be built according to the same rules as URLFor. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
method string No post The type of method to use in the form tag (delete, get, patch, post, and put are the options).
multipart boolean No false Set to true if the form should be able to upload files.
route string No Name of a route that you have configured in config/routes.cfm.
controller string No Name of the controller to include in the URL.
action string No Name of the action to include in the URL.
key any No Key(s) to include in the URL.
params string No Any additional parameters to be set in the query string (example: wheels=cool&x=y). Please note that Wheels uses the & and = characters to split the parameters and encode them properly for you. However, if you need to pass in & or = as part of the value, then you need to encode them (and only them), example: a=cats%26dogs%3Dtrouble!&b=1.
anchor string No Sets an anchor name to be appended to the path.
onlyPath boolean No true If true, returns only the relative URL (no protocol, host name or port).
host string No Set this to override the current host.
protocol string No Set this to override the current protocol.
port numeric No 0 Set this to override the current port number.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic form posting to a specific action in the current controller
#startFormTag(action="create")#
    <!--- form controls go here --->
#endFormTag()#

// 2. Form targeting a different controller and action, using HTTP GET
#startFormTag(controller="search", action="results", method="get")#
    <!--- search fields --->
#endFormTag()#

// 3. Multipart form for file uploads
#startFormTag(action="upload", multipart=true)#
    <!--- file input and other controls --->
#endFormTag()#

// 4. Form using a named route with extra HTML attributes (id, class)
#startFormTag(route="newRegistration", id="registration-form", class="form-horizontal")#
    <!--- registration fields --->
#endFormTag()#

// 5. Form that sends a PUT request (e.g., update an existing record)
#startFormTag(action="update", key=params.key, method="put")#
    <!--- edit fields --->
#endFormTag()#

string()

Migrator Table Definition Functions any tabledefinition

adds string columns to table definition

Name Type Required Default Description
columnNames string No
limit any No
default any No
allowNull boolean No
// 1. Add a single string column to a new table
t = createTable(name='users');
	t.string(columnNames='username', limit=100, allowNull=false);
	t.string(columnNames='email', limit=255, allowNull=false);
	t.timestamps();
t.create();

// 2. Add multiple string columns at once with a default value
t = createTable(name='products');
	t.string(columnNames='name,sku,status', limit=100, default='', allowNull=false);
	t.integer(columnNames='stock', default=0, allowNull=false);
	t.timestamps();
t.create();

// 3. Alter an existing table to add a string column with a limit
t = changeTable(name='orders');
	t.string(columnNames='trackingNumber', limit=50, allowNull=true);
t.change();

stripTags()

View Helpers Sanitization Functions string controller

Removes all HTML tags from a string.

Name Type Required Default Description
html string Yes The HTML to remove tag markup from.
encode boolean No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Strip all HTML tags from a string, leaving plain text
result = stripTags('<strong>CFWheels</strong> is a framework for <a href="http://www.adobe.com/products/coldfusion">ColdFusion</a>.');
// result -> "CFWheels is a framework for ColdFusion."

// 2. Strip tags from a richer HTML fragment
result = stripTags('<h1>Welcome</h1><p>This is a <em>great</em> framework.</p>');
// result -> "WelcomeThis is a great framework."

// 3. Strip tags while skipping XSS encoding (e.g. when you trust the source HTML)
result = stripTags('<p>Hello, <strong>world</strong>!</p>', encode=false);
// result -> "Hello, world!"

styleSheetLinkTag()

View Helpers Asset Functions string controller

Returns a link tag for a stylesheet (or several) based on the supplied arguments.

Name Type Required Default Description
sources string No The name of one or many CSS files in the stylesheets folder, minus the .css extension. Pass a full URL to generate a tag for an external style sheet. Can also be called with the source argument.
type string No text/css The type attribute for the link tag.
media string No all The media attribute for the link tag.
rel string No The rel attribute for the relation between the tag and href.
head boolean No false Set to true to place the output in the head area of the HTML page instead of the default behavior (which is to place the output where the function is called from).
delim string No , The delimiter to use for the list of CSS files.
encode boolean No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Include a single stylesheet from the `stylesheets` folder
// Generates: <link rel="stylesheet" href="/stylesheets/app.css" ...>
writeOutput(styleSheetLinkTag("app"));

// 2. Include multiple stylesheets with a comma-delimited list
// Generates two separate <link> tags for blog.css and comments.css
writeOutput(styleSheetLinkTag("blog,comments"));

// 3. Include a stylesheet for print media only
writeOutput(styleSheetLinkTag(sources="print", media="print"));

// 4. Include an external stylesheet via full URL
writeOutput(styleSheetLinkTag("https://fonts.googleapis.com/css2?family=Roboto"));

// 5. Push a stylesheet into the <head> from anywhere in the view
// The tag is injected into the <head> section rather than rendered inline
writeOutput(styleSheetLinkTag(sources="tabs", head=true));

// 6. Use a pipe delimiter instead of the default comma
writeOutput(styleSheetLinkTag(sources="reset|layout|theme", delim="|"));

submitTag()

View Helpers General Form Functions string controller

Builds and returns a string containing a submit button form control. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
value string No Save changes Message to display in the button form control.
image string No File name of the image file to use in the button form control.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic submit button inside a form
#startFormTag(action="save")#
    <!--- form controls go here --->
    #submitTag()#
#endFormTag()#
// -> <form action="/products/save" method="post">...<input type="submit" value="Save changes"></form>

// 2. Custom button label
#submitTag(value="Create Account")#
// -> <input type="submit" value="Create Account">

// 3. Image submit button
#submitTag(image="submit-button.png")#
// -> <input type="image" src="/images/submit-button.png">

// 4. Submit button with extra HTML attributes (class and id)
#submitTag(value="Place Order", class="btn btn-primary", id="order-submit")#
// -> <input type="submit" value="Place Order" class="btn btn-primary" id="order-submit">

// 5. Submit button wrapped with HTML using prepend and append
#submitTag(value="Save", prepend="<div class=""actions"">", append="</div>")#
// -> <div class="actions"><input type="submit" value="Save"></div>

subscribeToChannel()

void controller

Subscribe to a channel and stream events to the client via SSE. Opens a long-lived SSE connection that delivers matching events until the client disconnects or the timeout is reached. For the "memory" adapter, subscribes to the in-memory Channel engine and buffers events for delivery. For the "database" adapter, polls the wheels_events table at regular intervals.

Name Type Required Default Description
channel string Yes The channel name to subscribe to (e.g. "user.42").
events string No Comma-delimited list of event types to filter. Empty = all events.
lastEventId string No Resume from this event ID. Auto-detected from Last-Event-ID header if empty.
adapter string No "memory" (default) or "database".
pollInterval numeric No 2 Seconds between polls for database adapter (default 2).
timeout numeric No 300 Maximum connection duration in seconds (default 300 = 5 minutes).
heartbeatInterval numeric No 15 Seconds between keep-alive pings (default 15).

sum()

Model Class Statistics Functions any model

Calculates the sum of values for a given property. Uses the SQL function SUM. If no records can be found to perform the calculation on you can use the ifNull argument to decide what should be returned.

Name Type Required Default Description
property string Yes Name of the property to get the sum for (must be a property of a numeric data type).
where string No Maps to the WHERE clause of the query (or HAVING when necessary). The following operators are supported: =, !=, <>, <, <=, >, >=, LIKE, NOT LIKE, IN, NOT IN, IS NULL, IS NOT NULL, AND, and OR (note that the key words need to be written in upper case). You can also use parentheses to group statements. Nested queries not allowed. You do not need to specify the table name(s); Wheels will do that for you.
include string No Associations that should be included in the query using INNER or LEFT OUTER joins (which join type that is used depends on how the association has been set up in your model). If all included associations are set on the current model, you can specify them in a list (e.g. department,addresses,emails). You can build more complex include strings by using parentheses when the association is set on an included model, like album(artist(genre)), for example. These complex include strings only work when returnAs is set to query though.
distinct boolean No false When true, SUM returns the sum of unique values only.
parameterize any No true Set to true to use cfqueryparam on all columns, or pass in a list of property names to use cfqueryparam on those only.
ifNull any No The value returned if no records are found. Common usage is to set this to 0 to make sure a numeric value is always returned instead of a blank string.
includeSoftDeletes boolean No false Set to true to include soft-deleted records in the queries that this method runs.
group string No Maps to the GROUP BY clause of the query. You do not need to specify the table name(s); Wheels will do that for you.
// 1. Get the sum of all salaries
allSalaries = model("Employee").sum("salary");

// 2. Get the sum of all salaries for employees in a given country
allAustralianSalaries = model("Employee").sum(property="salary", include="country", where="countryname='Australia'");

// 3. Make sure a numeric value is always returned, even if there are no records analyzed by the query
salarySum = model("Employee").sum(property="salary", where="salary BETWEEN #params.min# AND #params.max#", ifNull=0);

// 4. Sum only distinct (unique) salary values
distinctSum = model("Employee").sum(property="salary", distinct=true);

// 5. Get the total salary per department using grouping
byDepartment = model("Employee").sum(property="salary", group="departmentId");
// byDepartment is a query with columns: departmentId, salarysum

switchTenant()

Configuration Multi-Tenancy void controller model mapper migrator migration tabledefinition

Switches the active tenant mid-request. Throws if the current tenant is locked (set by TenantResolver middleware) unless force is true.

Name Type Required Default Description
tenant struct Yes Struct with at minimum a dataSource key. Optional: id, config.
force boolean No false If true, overrides the lock set by TenantResolver middleware.
// 1. Switch to a different tenant mid-request (minimal required argument)
switchTenant(tenant = {dataSource = "tenant_db_acme"});

// 2. Switch with a full tenant struct (id and per-tenant config override)
switchTenant(
    tenant = {
        dataSource = "tenant_db_beta",
        id         = "beta",
        config     = {timeZone = "America/New_York"}
    }
);

// 3. Force-switch even when the current tenant is locked by TenantResolver middleware
switchTenant(
    tenant = {dataSource = "tenant_db_admin", id = "admin"},
    force  = true
);

table()

Model Configuration Miscellaneous Functions void model

Use this method to tell Wheels what database table to connect to for this model. You only need to use this method when your table naming does not follow the standard Wheels convention of a singular object name mapping to a plural table name. To not use a table for your model at all, call table(false).

Name Type Required Default Description
name any Yes Name of the table to map this model to.
// 1. Map the `User` model to a non-standard table name.
// In models/User.cfc
function config() {
	// Tell Wheels to use `tbl_USERS` instead of the default `users` table.
	table("tbl_USERS");
}

// 2. Map a model to a table with a legacy prefix.
// In models/Product.cfc
function config() {
	table("legacy_products");
}

// 3. Declare a model that has no backing database table at all.
// In models/ApiResponse.cfc
function config() {
	table(false);
}

tableName()

Model Class Miscellaneous Functions string model

Returns the name of the database table that this model is mapped to. This is a getter and takes no arguments — the table setter is table(). Calling tableName() with an argument has always been a silent no-op (CFML accepts the extra argument and the model keeps its convention table), a trap some 4.0-era docs taught as a setter. When error information is shown (development / testing — the same gate exists() uses above) it now fails loud; in production it stays a no-op so an upgrade never breaks a running app. See issue #3079.

// 1. Check what table the User model is mapped to (Wheels convention: singular model -> plural table)
name = model("User").tableName();
// name -> "users"

// 2. Check the table for a model that uses a custom table name (set via table() in config())
// In models/StaffMember.cfc: table("employees");
name = model("StaffMember").tableName();
// name -> "employees"

// 3. Use the table name dynamically in a log message or custom SQL fragment
tableUsed = model("Order").tableName();
writeOutput("Querying table: " & tableUsed);
// Outputs: Querying table: orders

telField()

View Helpers Form Object Functions string controller

Builds and returns a string containing a telephone field form control based on the supplied objectName and property. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
objectName any Yes The variable name of the object to build the form control for.
property string Yes The name of the property to use in the form control.
association string No The name of the association that the property is located on. Used for building nested forms that work with nested properties. If you are building a form with deep nesting, simply pass in a list to the nested object, and Wheels will figure it out.
position string No The position used when referencing a hasMany relationship in the association argument. Used for building nested forms that work with nested properties. If you are building a form with deep nestings, simply pass in a list of positions, and Wheels will figure it out.
label string No useDefaultLabel The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
errorElement string No span HTML tag to wrap the form control with when the object contains errors.
errorClass string No field-with-errors The class name of the HTML tag that wraps the form control when there are errors.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
<!--- Provide a `label` and the required `objectName` and `property` --->\n#telField(label="Phone Number", objectName="contact", property="phone")#\n\n<!--- Add a CSS class and a placeholder for formatting guidance --->\n#telField(label="Mobile", objectName="user", property="mobile", class="tel-input", placeholder="+1-555-000-0000")#\n\n<!--- Render telephone fields for each phone number in a nested association --->\n<fieldset>\n\t<legend>Phone Numbers</legend>\n\t<cfloop from="1" to="#ArrayLen(contact.phoneNumbers)#" index="i">\n\t\t#telField(label="Phone ##i#", objectName="contact", association="phoneNumbers", position=i, property="number")#\n\t</cfloop>\n</fieldset>

telFieldTag()

View Helpers Form Tag Functions string controller

Builds and returns a string containing a telephone field form control based on the supplied name. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
name string Yes Name to populate in tag's name attribute.
value string No Value to populate in tag's value attribute.
label string No The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic telephone field with a pre-filled value
#telFieldTag(name="phone", value="555-867-5309")#

// 2. Telephone field with a label and a CSS class
#telFieldTag(name="mobilePhone", value="", label="Mobile Phone", class="tel-input")#

// 3. Telephone field with label placement and prepend/append wrappers
#telFieldTag(name="officePhone", label="Office Phone", labelPlacement="before", prepend="<div class=""field"">", append="</div>")#

tenant()

Configuration Multi-Tenancy struct controller model mapper migrator migration tabledefinition

Returns the current tenant struct, or an empty struct if no tenant is active. The tenant struct contains: id, dataSource, config, and $locked. A tenant only counts as active when it carries a non-empty dataSource — the same test $tenantDataSource() applies before it routes a query. Anything else on the key reads as no tenant rather than being handed back as though it were a resolved one, so a malformed value degrades to a no-op instead of wrong behaviour (#3336). Every framework producer (switchTenant(), TenantResolver, Job.$restoreTenantContext(), TenantMigrator) already guarantees a non-empty dataSource, so this only filters foreign values.

// 1. Get the active tenant struct (when a tenant is set)
t = tenant();
// t -> {id: "acme", dataSource: "tenant_db_acme", config: {}, $locked: true}

// 2. Check whether a tenant is active before using its properties
t = tenant();
if (!structIsEmpty(t)) {
    writeOutput("Current tenant: " & t.id);
} else {
    writeOutput("No tenant active — using application defaults.");
}

// 3. Access a per-tenant config value set via switchTenant()
t = tenant();
if (structKeyExists(t, "config") && structKeyExists(t.config, "timeZone")) {
    writeOutput("Tenant time zone: " & t.config.timeZone);
}

text()

Migrator Table Definition Functions any tabledefinition

Adds text columns to table definition. In MySQL databases, you can specify different text sizes: - Regular TEXT (65KB) - default when no size is specified - MEDIUMTEXT (16MB) - specify size="mediumtext" - LONGTEXT (4GB) - specify size="longtext" For other database engines, the size parameter is ignored and the default text type is used.

Name Type Required Default Description
columnNames string No
default any No
allowNull boolean No
size string No
// 1. Add a single text column to a table
t.text("body");

// 2. Add multiple text columns at once
t.text("summary,description,notes");

// 3. Add a text column that defaults to an empty string and disallows nulls
t.text(columnNames="bio", default="", allowNull=false);

// 4. Add a MEDIUMTEXT column in MySQL (16MB capacity; ignored on other databases)
t.text(columnNames="content", size="mediumtext");

// 5. Add a LONGTEXT column in MySQL (4GB capacity; ignored on other databases)
t.text(columnNames="rawHtml", size="longtext");

// 6. Full migration example using text() inside createTable
t = createTable("articles");
t.string("title");
t.text("body");
t.text(columnNames="excerpt", allowNull=true);
t.timestamps();
t.create();

textArea()

View Helpers Form Object Functions string controller

Builds and returns a string containing a text area field form control based on the supplied objectName and property. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
objectName any Yes The variable name of the object to build the form control for.
property string Yes The name of the property to use in the form control.
association string No The name of the association that the property is located on. Used for building nested forms that work with nested properties. If you are building a form with deep nesting, simply pass in a list to the nested object, and Wheels will figure it out.
position string No The position used when referencing a hasMany relationship in the association argument. Used for building nested forms that work with nested properties. If you are building a form with deep nestings, simply pass in a list of positions, and Wheels will figure it out.
label string No useDefaultLabel The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
errorElement string No span HTML tag to wrap the form control with when the object contains errors.
errorClass string No field-with-errors The class name of the HTML tag that wraps the form control when there are errors.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic text area bound to a model object property
#textArea(objectName="article", property="overview", label="Overview")#

// 2. Text area with custom rows/cols attributes and a placeholder
#textArea(objectName="post", property="body", label="Body", rows=10, cols=60, placeholder="Write your post here...")#

// 3. Text areas for a nested hasMany association (screenshots)
<fieldset>
	<legend>Screenshots</legend>
	<cfloop from="1" to="#ArrayLen(site.screenshots)#" index="i">
		#fileField(objectName="site", association="screenshots", position=i, property="file", label="File ##i#")#
		#textArea(objectName="site", association="screenshots", position=i, property="caption", label="Caption ##i#")#
	</cfloop>
</fieldset>

// 4. Text area with label placement after and appended helper text
#textArea(objectName="user", property="bio", label="Bio", labelPlacement="before", append="<small>Max 500 characters</small>")#

textAreaTag()

View Helpers Form Tag Functions string controller

Builds and returns a string containing a text area form control based on the supplied name. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
name string Yes Name to populate in tag's name attribute.
content string No Content to display in textarea on page load.
label string No The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic textarea with a label and pre-populated content from params
#textAreaTag(name="description", label="Description", content=params.description)#

// 2. Textarea without a label, adding extra HTML attributes via additional arguments
#textAreaTag(name="bio", rows="6", cols="40")#

// 3. Textarea with label placement controlled and content wrapped with HTML using prepend/append
#textAreaTag(name="notes", label="Notes", labelPlacement="before", prepend="<div class=""field"">", append="</div>")#

textField()

View Helpers Form Object Functions string controller

Builds and returns a string containing a text field form control based on the supplied objectName and property. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
objectName any Yes The variable name of the object to build the form control for.
property string Yes The name of the property to use in the form control.
association string No The name of the association that the property is located on. Used for building nested forms that work with nested properties. If you are building a form with deep nesting, simply pass in a list to the nested object, and Wheels will figure it out.
position string No The position used when referencing a hasMany relationship in the association argument. Used for building nested forms that work with nested properties. If you are building a form with deep nestings, simply pass in a list of positions, and Wheels will figure it out.
label string No useDefaultLabel The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
errorElement string No span HTML tag to wrap the form control with when the object contains errors.
errorClass string No field-with-errors The class name of the HTML tag that wraps the form control when there are errors.
type string No text Input type attribute. Common examples in HTML5 and later are text (default), email, tel, and url.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic text field bound to an object property
#textField(objectName="user", property="firstName", label="First Name")#

// 2. Use an HTML5 input type (email, tel, url, etc.) via the `type` argument
#textField(objectName="user", property="email", label="Email Address", type="email")#

// 3. Render fields for a hasMany association using `association` and `position`
<cfloop from="1" to="#ArrayLen(contact.phoneNumbers)#" index="i">
	#textField(objectName="contact", association="phoneNumbers", position=i, property="phoneNumber", label="Phone ##i#")#
</cfloop>

// 4. Wrap the field with extra markup using `prepend` and `append`
#textField(objectName="user", property="username", label="Username", prepend="<div class=""field"">", append="</div>")#

textFieldTag()

View Helpers Form Tag Functions string controller

Builds and returns a string containing a text field form control based on the supplied name. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
name string Yes Name to populate in tag's name attribute.
value string No Value to populate in tag's value attribute.
label string No The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
type string No text Input type attribute. Common examples in HTML5 and later are text (default), email, tel, and url.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic search field with a label and a pre-filled value from params
#textFieldTag(name="q", label="Search", value=params.q)#

// 2. Email input using the HTML5 type attribute
#textFieldTag(name="email", label="Email address", type="email", value=params.email)#

// 3. Field with label placed before the input and extra HTML attributes
#textFieldTag(name="username", label="Username", labelPlacement="before", class="form-control", placeholder="Enter username")#

// 4. Wrapping the input with Bootstrap input-group markup using prepend and append
#textFieldTag(name="website", label="Website", type="url", prepend="<div class=""input-group"">", append="</div>")#

time()

Migrator Table Definition Functions any tabledefinition

adds time columns to table definition

Name Type Required Default Description
columnNames string No
default any No
allowNull boolean No
// 1. Add a single time column to a new table
t = createTable(name='schedules');
	t.string(columnNames='title', limit=255, allowNull=false);
	t.time(columnNames='startTime', allowNull=false);
	t.timestamps();
t.create();

// 2. Add multiple time columns at once
t = createTable(name='shifts');
	t.string(columnNames='employeeName', limit=100, allowNull=false);
	t.time(columnNames='clockIn,clockOut', allowNull=false);
	t.timestamps();
t.create();

// 3. Add a nullable time column with a default to an existing table
t = changeTable(name='stores');
	t.time(columnNames='openTime', allowNull=true, default='09:00:00');
t.change();

timeAgoInWords()

Global Helpers Date Functions any controller model mapper migrator migration tabledefinition

Returns a string describing the approximate time difference between the date passed in and the current date.

Name Type Required Default Description
fromTime date Yes Date to compare from.
includeSeconds boolean No false Whether or not to include the number of seconds in the returned string.
toTime date No [runtime expression] Date to compare to.
// 1. Show how long ago a date was (relative to now)
aWhileAgo = DateAdd("d", -90, Now());
// Returns something like "3 months"
writeOutput(timeAgoInWords(aWhileAgo));

// 2. Include seconds for a very recent timestamp
justNow = DateAdd("s", -8, Now());
// Returns "less than 10 seconds"
writeOutput(timeAgoInWords(fromTime=justNow, includeSeconds=true));

// 3. Compare against a specific reference point instead of now
postDate = CreateDateTime(2024, 1, 15, 9, 0, 0);
referenceDate = CreateDateTime(2024, 3, 20, 9, 0, 0);
// Returns "about 2 months"
writeOutput(timeAgoInWords(fromTime=postDate, toTime=referenceDate));

timeSelect()

View Helpers Form Object Functions string controller

Builds and returns a string containing three select form controls for hour, minute, and second based on the supplied objectName and property.

Name Type Required Default Description
objectName any No The variable name of the object to build the form control for.
property string No The name of the property to use in the form control.
association string No The name of the association that the property is located on. Used for building nested forms that work with nested properties. If you are building a form with deep nesting, simply pass in a list to the nested object, and Wheels will figure it out.
position string No The position used when referencing a hasMany relationship in the association argument. Used for building nested forms that work with nested properties. If you are building a form with deep nestings, simply pass in a list of positions, and Wheels will figure it out.
order string No hour,minute,second Use to change the order of or exclude time select tags.
separator string No : Use to change the character that is displayed between the time select tags.
minuteStep numeric No 1 Pass in 10 to only show minute 10, 20, 30, etc.
secondStep numeric No 1 Pass in 10 to only show seconds 10, 20, 30, etc.
includeBlank any No false Whether to include a blank option in the select form control. Pass true to include a blank line or a string that should represent what display text should appear for the empty value (for example, "- Select One -").
label string No false The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
errorElement string No span HTML tag to wrap the form control with when the object contains errors.
errorClass string No field-with-errors The class name of the HTML tag that wraps the form control when there are errors.
combine boolean No Set to false to not combine the select parts into a single DateTime object.
twelveHour boolean No false whether to display the hours in 24 or 12 hour format. 12 hour format has AM/PM drop downs
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
<!--- Basic time select bound to a model object (hour, minute, second) --->
#timeSelect(objectName="business", property="openUntil")#

<!--- Show fields for hour and minute only --->
#timeSelect(objectName="business", property="openUntil", order="hour,minute")#

<!--- Only show 15-minute intervals --->
#timeSelect(objectName="appointment", property="dateTimeStart", minuteStep=15)#

<!--- Display in 12-hour format with AM/PM --->
#timeSelect(objectName="appointment", property="dateTimeStart", twelveHour=true)#

<!--- Include a blank option and use a custom separator --->
#timeSelect(objectName="shift", property="startTime", includeBlank="- Select -", separator=" | ")#

timeSelectTags()

View Helpers Form Tag Functions string controller

Builds and returns a string containing three select form controls for hour, minute, and second based on name.

Name Type Required Default Description
name string Yes Name to populate in tag's name attribute.
selected string No Value of option that should be selected by default.
order string No hour,minute,second Use to change the order of or exclude time select tags.
separator string No : Use to change the character that is displayed between the time select tags.
minuteStep numeric No 1 Pass in 10 to only show minute 10, 20, 30, etc.
secondStep numeric No 1 Pass in 10 to only show seconds 10, 20, 30, etc.
includeBlank any No false Whether to include a blank option in the select form control. Pass true to include a blank line or a string that should represent what display text should appear for the empty value (for example, "- Select One -").
label string No The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
combine boolean No Set to false to not combine the select parts into a single DateTime object.
twelveHour boolean No false whether to display the hours in 24 or 12 hour format. 12 hour format has AM/PM drop downs
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic usage - render hour, minute, and second selects unbound from a model object
#timeSelectTags(name="timeOfMeeting", selected=params.timeOfMeeting)#

// 2. Show only hour and minute fields
#timeSelectTags(name="timeOfMeeting", selected=params.timeOfMeeting, order="hour,minute")#

// 3. Use 12-hour format with AM/PM and jump minutes in 15-minute increments
#timeSelectTags(name="appointmentTime", selected=params.appointmentTime, twelveHour=true, minuteStep=15, order="hour,minute")#

// 4. Include a blank option and add a label
#timeSelectTags(name="startTime", selected=params.startTime, includeBlank=true, label="Start Time")#

timestamp()

Migrator Table Definition Functions any tabledefinition

adds timestamp columns to table definition

Name Type Required Default Description
columnNames string No
default any No
allowNull boolean No
columnType string No datetime
// 1. Add a single timestamp column to a new table
t = createTable(name='sessions');
	t.string(columnNames='token', limit=64, allowNull=false);
	t.timestamp(columnNames='expiresAt', allowNull=false);
	t.timestamps();
t.create();

// 2. Add multiple timestamp columns at once
t = createTable(name='events');
	t.string(columnNames='name', limit=255, allowNull=false);
	t.timestamp(columnNames='startsAt,endsAt', allowNull=false);
	t.timestamps();
t.create();

// 3. Add a nullable timestamp column with a default to an existing table
t = changeTable(name='articles');
	t.timestamp(columnNames='publishedAt', allowNull=true, default='NOW()');
t.change();

// 4. Override the underlying column type (e.g. use 'timestamp' instead of the default 'datetime')
t = createTable(name='logs');
	t.string(columnNames='message', limit=255, allowNull=false);
	t.timestamp(columnNames='occurredAt', columnType='timestamp', allowNull=false);
	t.timestamps();
t.create();

timestamps()

Migrator Table Definition Functions any tabledefinition

adds Wheels convention automatic timestamp and soft delete columns to table definition

// 1. Add Wheels convention timestamp and soft-delete columns to a new table
// Adds createdAt, updatedAt, and deletedAt (all nullable datetime columns)
t = createTable(name='articles');
	t.string(columnNames='title', limit=255, allowNull=false);
	t.text(columnNames='body');
	t.timestamps();
t.create();

// 2. Use timestamps() alongside other column definitions in a full migration
t = createTable(name='posts');
	t.string(columnNames='title', limit=255, allowNull=false);
	t.string(columnNames='slug', limit=255, allowNull=false);
	t.text(columnNames='body');
	t.boolean(columnNames='published', default=false, allowNull=false);
	t.references(columnNames='author');
	t.timestamps();
t.create();

timeUntilInWords()

Global Helpers Date Functions string controller model mapper migrator migration tabledefinition

Returns a string describing the approximate time difference between the current date and the date passed in.

Name Type Required Default Description
toTime date Yes Date to compare to.
includeSeconds boolean No false Whether or not to include the number of seconds in the returned string.
fromTime date No [runtime expression] Date to compare from.
// 1. Show approximate time until a future date
nextYear = DateAdd("yyyy", 1, Now());
writeOutput(timeUntilInWords(nextYear));
// -> "about 1 year"

// 2. Include seconds for a near-future time
soonish = DateAdd("s", 8, Now());
writeOutput(timeUntilInWords(toTime=soonish, includeSeconds=true));
// -> "less than 10 seconds"

// 3. Compare two explicit dates (custom fromTime)
launchDate = CreateDate(2025, 6, 1);
deadline   = CreateDate(2025, 9, 15);
writeOutput(timeUntilInWords(toTime=deadline, fromTime=launchDate));
// -> "about 3 months"

titleize()

Global Helpers String Functions string controller model mapper migrator migration tabledefinition

Capitalizes all words in the text to create a nicer looking title.

Name Type Required Default Description
word string Yes The text to turn into a title.
// 1. Capitalize each word in a plain sentence
result = titleize("the quick brown fox");
// result -> "The Quick Brown Fox"

// 2. Capitalize a page title that is already mixed case
result = titleize("CFWheels is a framework for ColdFusion");
// result -> "CFWheels Is A Framework For ColdFusion"

// 3. Use titleize to format a record name for display
article = model("Article").findByKey(params.key);
writeOutput(titleize(article.title));

toggle()

Model Object CRUD Functions boolean model

Assigns to the property specified the opposite of the property's current boolean value. Throws an error if the property cannot be converted to a boolean value. Returns this object if save called internally is false.

Name Type Required Default Description
property string Yes
save boolean No true Argument to decide whether save the property after it has been toggled.
// 1. Toggle a boolean property and save it immediately (default behavior)
user = model("User").findByKey(58);
// Returns true if the record was saved successfully, false otherwise
isSuccess = user.toggle("isActive");

// 2. Toggle a boolean property without saving to the database
user = model("User").findByKey(58);
user.toggle(property="isActive", save=false);
// user.isActive is now flipped in memory; call user.save() later to persist

// 3. Use the dynamic toggle helper generated by Wheels
user = model("User").findByKey(58);
isSuccess = user.toggleIsActive();

truncate()

Global Helpers String Functions string controller model mapper migrator migration tabledefinition

Truncates text to the specified length and replaces the last characters with the specified truncate string (which defaults to "...").

Name Type Required Default Description
text string Yes The text to truncate.
length numeric No 30 Length to truncate the text to.
truncateString string No ... String to replace the last characters with.
// 1. Truncate to a specific character length (defaults to "..." suffix)
truncated = truncate(text="CFWheels is a framework for ColdFusion", length=20);
// truncated -> "CFWheels is a fra..."

// 2. Use a custom truncate string instead of the default ellipsis
truncated = truncate(text="CFWheels is a framework for ColdFusion", truncateString=" (more)");
// truncated -> "CFWheels is a framework fo (more)"

// 3. Text shorter than the length limit is returned unchanged
truncated = truncate(text="Hello", length=30);
// truncated -> "Hello"

uniqueidentifier()

Migrator Table Definition Functions any tabledefinition

adds UUID columns to table definition

Name Type Required Default Description
columnNames string No
default any No newid()
allowNull boolean No
// 1. Add a single UUID column with the default newid() value
t = createTable(name='sessions');
	t.uniqueidentifier(columnNames='token');
	t.timestamps();
t.create();

// 2. Add a UUID column that allows NULL values
t = createTable(name='invitations');
	t.string(columnNames='email', limit=255, allowNull=false);
	t.uniqueidentifier(columnNames='inviteToken', allowNull=true);
	t.timestamps();
t.create();

// 3. Alter an existing table to add multiple UUID columns at once
t = changeTable(name='documents');
	t.uniqueidentifier(columnNames='publicId,shareToken', allowNull=false);
t.change();

up()

Migrator Migration Functions void migration

Migrates up: will be executed when migrating your schema forward Along with down(), these are the two main functions in any migration file Only available in a migration CFC

// 1. Create a new table (typical migration forward)
function up() {
	var state = {};
	transaction {
		try {
			t = createTable(name="posts");
			t.string(columnNames="title", limit=255);
			t.text(columnNames="body");
			t.boolean(columnNames="published", default=0);
			t.timestamps();
			t.create();
		} catch (any e) {
			state.exception = e;
		}

		if (structKeyExists(state, "exception")) {
			transaction action="rollback";
			throw(
				errorCode = "1",
				detail    = state.exception.detail,
				message   = state.exception.message,
				type      = "any"
			);
		} else {
			transaction action="commit";
		}
	}
}

// 2. Add a column to an existing table
function up() {
	var state = {};
	transaction {
		try {
			addColumn(table="users", columnType="string", columnName="avatarUrl", limit=500, allowNull=true);
		} catch (any e) {
			state.exception = e;
		}

		if (structKeyExists(state, "exception")) {
			transaction action="rollback";
			throw(
				errorCode = "1",
				detail    = state.exception.detail,
				message   = state.exception.message,
				type      = "any"
			);
		} else {
			transaction action="commit";
		}
	}
}

// 3. Run raw SQL and seed initial data in the same migration
function up() {
	var state = {};
	transaction {
		try {
			execute("ALTER TABLE products ADD COLUMN sku VARCHAR(50)");
			addRecord(table="settings", key="maintenance_mode", value="false");
		} catch (any e) {
			state.exception = e;
		}

		if (structKeyExists(state, "exception")) {
			transaction action="rollback";
			throw(
				errorCode = "1",
				detail    = state.exception.detail,
				message   = state.exception.message,
				type      = "any"
			);
		} else {
			transaction action="commit";
		}
	}
}

update()

Model Object CRUD Functions boolean model

Updates the object with the supplied properties and saves it to the database. Returns true if the object was saved successfully to the database and false otherwise.

Name Type Required Default Description
properties struct No [runtime expression] The properties you want to set on the object (can also be passed in as named arguments).
parameterize any No true Set to true to use cfqueryparam on all columns, or pass in a list of property names to use cfqueryparam on those only.
reload boolean No false Set to true to force Wheels to query the database even though an identical query for this model may have been run in the same request. (The default in Wheels is to get the second query from the model's request-level cache.)
validate boolean No true Set to false to skip validations for this operation.
transaction string No [runtime expression] Set this to commit to update the database, rollback to run all the database queries but not commit them, or none to skip transaction handling altogether.
callbacks boolean No true Set to false to disable callbacks for this method.
allowExplicitTimestamps boolean No false Set this to true to allow explicit assignment of createdAt or updatedAt properties
// 1. Find a post and update its title
post = model("Post").findByKey(33);
post.update(title="New version of Wheels just released");

// 2. Update multiple properties from form/URL params on an existing object
post = model("Post").findByKey(params.key);
isSuccess = post.update(title="New version of Wheels just released", properties=params.post);

// 3. Skip validations when updating (useful for admin operations)
post = model("Post").findByKey(params.key);
isSuccess = post.update(properties=params.post, validate=false);

// 4. Scoped call via a hasOne association (setBio calls bio.update(authorId=author.id) internally)
author = model("Author").findByKey(params.authorId);
bio = model("Bio").findByKey(params.bioId);
author.setBio(bio);

// 5. Scoped call via a hasMany association (addCar calls car.update(ownerId=owner.id) internally)
anOwner = model("Owner").findByKey(params.ownerId);
aCar = model("Car").findByKey(params.carId);
anOwner.addCar(aCar);

// 6. Scoped call to disassociate a record (removeComment calls comment.update(postId="") internally)
aPost = model("Post").findByKey(params.postId);
aComment = model("Comment").findByKey(params.commentId);
aPost.removeComment(aComment);

updateAll()

Model Class Update Functions numeric model

Updates all properties for the records that match the where argument. Property names and values can be passed in either using named arguments or as a struct to the properties argument. By default, objects will not be instantiated and therefore callbacks and validations are not invoked. You can change this behavior by passing in instantiate=true. This method returns the number of records that were updated.

Name Type Required Default Description
where string No Maps to the WHERE clause of the query (or HAVING when necessary). The following operators are supported: =, !=, <>, <, <=, >, >=, LIKE, NOT LIKE, IN, NOT IN, IS NULL, IS NOT NULL, AND, and OR (note that the key words need to be written in upper case). You can also use parentheses to group statements. Nested queries not allowed. You do not need to specify the table name(s); Wheels will do that for you.
include string No Associations that should be included in the query using INNER or LEFT OUTER joins (which join type that is used depends on how the association has been set up in your model). If all included associations are set on the current model, you can specify them in a list (e.g. department,addresses,emails). You can build more complex include strings by using parentheses when the association is set on an included model, like album(artist(genre)), for example. These complex include strings only work when returnAs is set to query though.
properties struct No [runtime expression] The properties you want to set on the object (can also be passed in as named arguments).
reload boolean No false Set to true to force Wheels to query the database even though an identical query for this model may have been run in the same request. (The default in Wheels is to get the second query from the model's request-level cache.)
parameterize any No true Set to true to use cfqueryparam on all columns, or pass in a list of property names to use cfqueryparam on those only.
instantiate boolean No false Whether or not to instantiate the object(s) first. When objects are not instantiated, any callbacks and validations set on them will be skipped.
useIndex struct No [runtime expression] If you want to specify table index hints, pass in a structure of index names using your model names as the structure keys. Eg: {user="idx_users", post="idx_posts"}. This feature is only supported by MySQL and SQL Server.
validate boolean No true Set to false to skip validations for this operation.
transaction string No [runtime expression] Set this to commit to update the database, rollback to run all the database queries but not commit them, or none to skip transaction handling altogether.
callbacks boolean No true Set to false to disable callbacks for this method.
includeSoftDeletes boolean No false Set to true to include soft-deleted records in the queries that this method runs.
// 1. Update a single property on all matching records (returns count of updated rows)
recordsUpdated = model("post").updateAll(published=1, where="published=0");

// 2. Update multiple properties on matching records using named arguments
recordsUpdated = model("post").updateAll(
	published=1,
	publishedAt=Now(),
	where="published=0"
);

// 3. Update using a properties struct instead of named arguments
props = {status="archived", updatedBy="system"};
recordsUpdated = model("post").updateAll(properties=props, where="createdAt < '#DateAdd("yyyy", -2, Now())#'");

// 4. Instantiate each matching object so that callbacks and validations run
recordsUpdated = model("user").updateAll(active=0, where="lastLoginAt < '#DateAdd("d", -365, Now())#'", instantiate=true);

// 5. Scoped call via a hasMany association — equivalent to
//    model("comment").updateAll(postId="", where="postId=#post.id#")
post = model("post").findByKey(params.postId);
post.removeAllComments();

updateByKey()

Model Class Update Functions boolean model

Finds the object with the supplied key and saves it (if validation permits it) with the supplied properties and / or named arguments. Property names and values can be passed in either using named arguments or as a struct to the properties argument. Returns true if the object was found and updated successfully, false otherwise.

Name Type Required Default Description
key any Yes Primary key value(s) of the record to fetch. Separate with comma if passing in multiple primary key values. Accepts a string, list, or a numeric value.
properties struct No [runtime expression] The properties you want to set on the object (can also be passed in as named arguments).
reload boolean No false Set to true to force Wheels to query the database even though an identical query for this model may have been run in the same request. (The default in Wheels is to get the second query from the model's request-level cache.)
validate boolean No true Set to false to skip validations for this operation.
transaction string No [runtime expression] Set this to commit to update the database, rollback to run all the database queries but not commit them, or none to skip transaction handling altogether.
callbacks boolean No true Set to false to disable callbacks for this method.
includeSoftDeletes boolean No false Set to true to include soft-deleted records in the queries that this method runs.
// 1. Update a post using a positional key and a params struct
result = model("post").updateByKey(33, params.post);

// 2. Update a post using named arguments
result = model("post").updateByKey(key=33, title="New version of Wheels just released", published=1);

// 3. Skip validations when updating a record (useful for admin operations)
result = model("post").updateByKey(key=33, validate=false, status="archived");

// 4. Include soft-deleted records when looking up the key to update
result = model("post").updateByKey(key=33, includeSoftDeletes=true, restoredAt=Now());

updateOne()

Model Class Update Functions boolean model

Gets an object based on the arguments used and updates it with the supplied properties. Returns true if an object was found and updated successfully, false otherwise.

Name Type Required Default Description
where string No Maps to the WHERE clause of the query (or HAVING when necessary). The following operators are supported: =, !=, <>, <, <=, >, >=, LIKE, NOT LIKE, IN, NOT IN, IS NULL, IS NOT NULL, AND, and OR (note that the key words need to be written in upper case). You can also use parentheses to group statements. Nested queries not allowed. You do not need to specify the table name(s); Wheels will do that for you.
order string No Maps to the ORDER BY clause of the query. You do not need to specify the table name(s); Wheels will do that for you.
properties struct No [runtime expression] The properties you want to set on the object (can also be passed in as named arguments).
reload boolean No false Set to true to force Wheels to query the database even though an identical query for this model may have been run in the same request. (The default in Wheels is to get the second query from the model's request-level cache.)
validate boolean No true Set to false to skip validations for this operation.
useIndex struct No [runtime expression] If you want to specify table index hints, pass in a structure of index names using your model names as the structure keys. Eg: {user="idx_users", post="idx_posts"}. This feature is only supported by MySQL and SQL Server.
transaction string No [runtime expression] Set this to commit to update the database, rollback to run all the database queries but not commit them, or none to skip transaction handling altogether.
callbacks boolean No true Set to false to disable callbacks for this method.
includeSoftDeletes boolean No false
// 1. Update the most recently released product by setting its `featured` flag
result = model("Product").updateOne(order="releaseDate DESC", featured=1);

// 2. Update a specific record matching a `where` clause
result = model("Order").updateOne(where="status='pending' AND createdAt < '#DateAdd('d', -7, Now())#'", status="expired");

// 3. Skip validations when updating, e.g. to force a status change
result = model("Article").updateOne(where="status='draft'", order="createdAt ASC", status="published", validate=false);

// 4. Scoped call via a `hasOne` association (calls `updateOne` internally)
// Given `hasOne(name="profile")` on the User model:
aUser = model("User").findByKey(params.userId);
aUser.removeProfile();

updateProperty()

Model Object CRUD Functions boolean model

Updates a single property and saves the record without going through the normal validation procedure. This is especially useful for boolean flags on existing records.

Name Type Required Default Description
property string No Name of the property to update the value for globally.
value any No Value to set on the given property globally.
parameterize any No true Set to true to use cfqueryparam on all columns, or pass in a list of property names to use cfqueryparam on those only.
transaction string No [runtime expression] Set this to commit to update the database, rollback to run all the database queries but not commit them, or none to skip transaction handling altogether.
callbacks boolean No true Set to false to disable callbacks for this method.
// 1. Set a boolean flag on an existing record (the primary use case)
product = model("Product").findByKey(56);
product.updateProperty("new", 1);

// 2. Mark a user account as active without triggering validations
user = model("User").findByKey(params.userId);
user.updateProperty("active", true);

// 3. Update a property and skip callbacks
post = model("Post").findByKey(params.id);
post.updateProperty(property="featured", value=true, callbacks=false);

updateRecord()

Migrator Migration Functions void migration

Updates an existing record in a table Only available in a migration CFC

Name Type Required Default Description
table string Yes The table name where the record is
where string No The where clause, i.e admin = 1
// 1. Update a single column for all rows in a table
updateRecord(
    table = "settings",
    value = "My Updated App"
);

// 2. Update specific columns using a where clause to target matching rows
updateRecord(
    table = "users",
    where = "role = 'guest'",
    active = false
);

// 3. Update multiple columns during a migration's up() function
component extends="wheels.migrator.Migration" {
    function up() {
        updateRecord(
            table = "users",
            where = "id = 1",
            firstName = "Bruce",
            lastName = "Wayne",
            email = "bruce@wayneenterprises.com"
        );
    }
    function down() {
        updateRecord(
            table = "users",
            where = "id = 1",
            firstName = "Clark",
            lastName = "Kent",
            email = "clark@dailyplanet.com"
        );
    }
}

upsertAll()

Model Class Create Functions struct model

Inserts or updates multiple records in a single batch operation (upsert). Uses database-specific conflict resolution syntax (e.g., ON CONFLICT ... DO UPDATE for PostgreSQL/SQLite). The uniqueBy argument specifies which properties form the unique constraint for conflict detection.

Name Type Required Default Description
records array Yes Array of structs, each containing property name/value pairs.
uniqueBy string Yes Comma-delimited list of property names that form the unique constraint for conflict detection.
timestamps boolean No true Set to false to skip automatic createdAt/updatedAt timestamping.
transaction string No [runtime expression] Set this to commit to update the database, rollback to run all the database queries but not commit them, or none to skip transaction handling altogether.
parameterize any No true Set to true to use cfqueryparam on all columns, or pass in a list of property names to use cfqueryparam on those only.
// 1. Upsert a batch of products using their SKU as the unique constraint
records = [
    {sku: "WIDGET-001", name: "Widget Standard", price: 9.99, stock: 100},
    {sku: "WIDGET-002", name: "Widget Deluxe",   price: 19.99, stock: 50},
    {sku: "GADGET-001", name: "Gadget Pro",       price: 49.99, stock: 25}
];
result = model("Product").upsertAll(records=records, uniqueBy="sku");
// result -> {upsertedCount: 3}

// 2. Upsert with a composite unique constraint (e.g., userId + date for daily stats)
stats = [
    {userId: 1, reportDate: "2024-06-01", pageViews: 42, clicks: 7},
    {userId: 2, reportDate: "2024-06-01", pageViews: 18, clicks: 3}
];
result = model("DailyStat").upsertAll(records=stats, uniqueBy="userId,reportDate");
// result -> {upsertedCount: 2}

// 3. Upsert without automatic timestamps (e.g., when importing legacy data)
imports = [
    {externalId: "EXT-100", title: "Legacy Record A", status: "active"},
    {externalId: "EXT-101", title: "Legacy Record B", status: "archived"}
];
result = model("ImportedRecord").upsertAll(
    records    = imports,
    uniqueBy   = "externalId",
    timestamps = false
);
// result -> {upsertedCount: 2}

urlField()

View Helpers Form Object Functions string controller

Builds and returns a string containing a URL field form control based on the supplied objectName and property. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
objectName any Yes The variable name of the object to build the form control for.
property string Yes The name of the property to use in the form control.
association string No The name of the association that the property is located on. Used for building nested forms that work with nested properties. If you are building a form with deep nesting, simply pass in a list to the nested object, and Wheels will figure it out.
position string No The position used when referencing a hasMany relationship in the association argument. Used for building nested forms that work with nested properties. If you are building a form with deep nestings, simply pass in a list of positions, and Wheels will figure it out.
label string No useDefaultLabel The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
errorElement string No span HTML tag to wrap the form control with when the object contains errors.
errorClass string No field-with-errors The class name of the HTML tag that wraps the form control when there are errors.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic URL field bound to an object property
#urlField(objectName="profile", property="websiteUrl")#

// 2. URL field with a custom label and a CSS class
#urlField(label="Website URL", objectName="profile", property="websiteUrl", class="form-control")#

// 3. Nested URL field for a contacts association (hasMany)
<cfloop from="1" to="#ArrayLen(company.contacts)#" index="i">
	#urlField(label="Contact Website ##i#", objectName="company", association="contacts", position=i, property="websiteUrl")#
</cfloop>

urlFieldTag()

View Helpers Form Tag Functions string controller

Builds and returns a string containing a URL field form control based on the supplied name. Note: Pass any additional arguments like class, rel, and id, and the generated tag will also include those values as HTML attributes.

Name Type Required Default Description
name string Yes Name to populate in tag's name attribute.
value string No Value to populate in tag's value attribute.
label string No The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic URL field with a label
#urlFieldTag(name="website", label="Website")#

// 2. Pre-filled with a value from params and a placeholder attribute
#urlFieldTag(name="homepage", label="Homepage", value=params.homepage, placeholder="https://example.com")#

// 3. Label placed before the field with an extra CSS class
#urlFieldTag(name="profileUrl", label="Profile URL", labelPlacement="before", class="form-control")#

// 4. Field wrapped with markup using prepend and append
#urlFieldTag(name="website", label="Website", prepend="<div class=""input-group"">", append="</div>")#

URLFor()

Global Helpers Miscellaneous Functions string controller model mapper migrator migration tabledefinition

Creates an internal URL based on supplied arguments.

Name Type Required Default Description
route string No Name of a route that you have configured in config/routes.cfm.
controller string No Name of the controller to include in the URL.
action string No Name of the action to include in the URL.
key any No Key(s) to include in the URL.
params string No Any additional parameters to be set in the query string (example: wheels=cool&x=y). Please note that Wheels uses the & and = characters to split the parameters and encode them properly for you. However, if you need to pass in & or = as part of the value, then you need to encode them (and only them), example: a=cats%26dogs%3Dtrouble!&b=1.
anchor string No Sets an anchor name to be appended to the path.
onlyPath boolean No true If true, returns only the relative URL (no protocol, host name or port).
host string No Set this to override the current host.
protocol string No Set this to override the current protocol.
port numeric No 0 Set this to override the current port number.
encode boolean No true Encode URL parameters using EncodeForURL(). Please note that this does not make the string safe for placement in HTML attributes, for that you need to wrap the result in EncodeForHtmlAttribute() or use linkTo(), startFormTag() etc instead.
// 1. Create the URL for the `logOut` action on the `account` controller, typically resulting in `/account/log-out`
urlFor(controller="account", action="logOut")

// 2. Create a URL with an anchor appended to it
urlFor(action="comments", anchor="comment10")

// 3. Create a URL based on a named route that expects `categorySlug` and `productSlug` params
urlFor(route="product", categorySlug="accessories", productSlug="battery-charger")

// 4. Generate an absolute URL (including protocol and host) to use in an email or external link
urlFor(controller="account", action="confirm", key=user.key(), onlyPath=false, protocol="https")

// 5. Append extra query string params not covered by the route pattern
urlFor(controller="products", action="index", params="sort=price&dir=asc")

usesLayout()

Controller Configuration Functions void controller

Used within a controller's config() function to specify controller- or action-specific layouts.

Name Type Required Default Description
template string Yes Name of the layout template or function name you want to use.
ajax string No Name of the layout template you want to use for AJAX requests.
except string No List of actions that should not get the layout.
only string No List of actions that should only get the layout.
useDefault boolean No true When specifying conditions or a function, pass in true to use the default layout.cfm if none of the conditions are met.
// 1. Use a custom layout for the entire controller, except for one action.
// Declared inside the controller's config() function.
usesLayout(template="myLayout", except="myAjax");

// 2. Apply a custom layout only to specific actions; all other actions
// use the default layout.cfm.
usesLayout(template="myLayout", only="termsOfService,shippingPolicy");

// 3. Serve a lightweight layout for AJAX requests while normal requests
// still receive the full layout.
usesLayout(template="myLayout", ajax="ajaxLayout");

// 4. Delegate layout selection to a private function. The function receives
// the current action name and should return the layout template name or
// true to fall back to the default layout.cfm.
usesLayout("chooseLayout");

// Example chooseLayout() function in the same controller:
// private function chooseLayout(action) {
//   if (action == "print") return "printLayout";
//   return true; // fall back to default layout.cfm
// }

// 5. Use a function-based layout but fall back to layout.cfm when the
// function returns nothing (useDefault defaults to true).
usesLayout(template="chooseLayout", useDefault=true);

valid()

Model Object Error Functions boolean model

Runs the validation on the object and returns true if it passes it. Wheels will run the validation process automatically whenever an object is saved to the database, but sometimes it's useful to be able to run this method to see if the object is valid without saving it to the database.

Name Type Required Default Description
callbacks boolean No true Set to false to disable callbacks for this method.
validateAssociations boolean No false
// 1. Check if a new user object passes validation before proceeding
user = model("User").new(params.user);

if (user.valid()) {
    // object passed all validations, safe to proceed
    redirectTo(action="dashboard");
} else {
    renderView(action="new");
}

// 2. Validate without running before/after validation callbacks
user = model("User").new(params.user);

if (user.valid(callbacks=false)) {
    user.save(callbacks=false);
}

// 3. Validate the object and any associated (nested) objects together
order = model("Order").new(params.order);

if (order.valid(validateAssociations=true)) {
    order.save();
} else {
    // errors may include issues from associated line items
    writeOutput(order.errorsAsHTML());
}

validate()

Model Configuration Validation Functions void model

Registers method(s) that should be called to validate objects before they are saved.

Name Type Required Default Description
methods string No Method name or list of method names to call. Can also be called with the method argument.
condition string No String expression to be evaluated that decides if validation will be run (if the expression returns true validation will run).
unless string No String expression to be evaluated that decides if validation will be run (if the expression returns false validation will run).
when string No onSave Pass in onCreate or onUpdate to limit when this validation occurs (by default validation will occur on both create and update, i.e. onSave).
// 1. Register a custom validation method to run on every save
function config() {
	// `checkPhoneNumber` will be called whenever an object is created or updated.
	validate("checkPhoneNumber");
}

function checkPhoneNumber() {
	// Make sure the area code is `614`.
	return Left(this.phoneNumber, 3) == "614";
}

// 2. Register multiple custom validation methods at once
function config() {
	validate(methods="checkPhoneNumber,checkEmailDomain");
}

// 3. Limit validation to create or update only
function config() {
	// Only run `checkTrialExpiry` when updating an existing record.
	validate(methods="checkTrialExpiry", when="onUpdate");
}

// 4. Run a custom validation only when a condition is met
function config() {
	// `checkBillingAddress` is skipped when the order is free.
	validate(methods="checkBillingAddress", condition="this.totalAmount gt 0");
}

// 5. Skip a custom validation when an `unless` expression is true
function config() {
	// `checkCreditCard` is skipped for admin users.
	validate(methods="checkCreditCard", unless="this.isAdmin");
}

validateOnCreate()

Model Configuration Validation Functions void model

Registers method(s) that should be called to validate new objects before they are inserted.

Name Type Required Default Description
methods string No Method name or list of method names to call. Can also be called with the method argument.
condition string No String expression to be evaluated that decides if validation will be run (if the expression returns true validation will run).
unless string No String expression to be evaluated that decides if validation will be run (if the expression returns false validation will run).
// 1. Register a custom method to validate new objects before insert
function config() {
	// `checkPhoneNumber` will only be called when creating a new record.
	validateOnCreate("checkPhoneNumber");
}

function checkPhoneNumber() {
	// Make sure area code is `614`.
	return Left(this.phoneNumber, 3) == "614";
}

// 2. Register multiple validation methods at once
function config() {
	validateOnCreate("checkPhoneNumber,checkReferralCode");
}

function checkPhoneNumber() {
	return Left(this.phoneNumber, 3) == "614";
}

function checkReferralCode() {
	if (Len(this.referralCode) && !isValidReferral(this.referralCode)) {
		addError(property="referralCode", message="Invalid referral code.");
	}
}

// 3. Only run the validation when a condition is met
function config() {
	// Only validate the phone number on create when the user is in the US.
	validateOnCreate(methods="checkPhoneNumber", condition="this.country eq 'US'");
}

function checkPhoneNumber() {
	return IsNumeric(this.phoneNumber);
}

validateOnUpdate()

Model Configuration Validation Functions void model

Registers method(s) that should be called to validate existing objects before they are updated.

Name Type Required Default Description
methods string No Method name or list of method names to call. Can also be called with the method argument.
condition string No String expression to be evaluated that decides if validation will be run (if the expression returns true validation will run).
unless string No String expression to be evaluated that decides if validation will be run (if the expression returns false validation will run).
// 1. Register a single custom validation method to run only on updates
component extends="Model" {
	function config() {
		validateOnUpdate("checkPhoneNumber");
	}

	private boolean function checkPhoneNumber() {
		// Make sure area code is 614
		return Left(this.phoneNumber, 3) == "614";
	}
}

// 2. Register multiple custom validation methods for updates
component extends="Model" {
	function config() {
		validateOnUpdate(methods="checkStatus,checkExpiry");
	}

	private boolean function checkStatus() {
		return ListFindNoCase("active,pending,suspended", this.status);
	}

	private boolean function checkExpiry() {
		return this.expiresAt > Now();
	}
}

// 3. Only validate when a condition is met (run only for premium accounts)
component extends="Model" {
	function config() {
		validateOnUpdate(methods="checkBillingAddress", condition="this.accountType eq 'premium'");
	}

	private boolean function checkBillingAddress() {
		return Len(Trim(this.billingAddress)) GT 0;
	}
}

validatesConfirmationOf()

Model Configuration Validation Functions void model

Validates that the value of the specified property also has an identical confirmation value. This is common when having a user type in their email address a second time to confirm, confirming a password by typing it a second time, etc. The confirmation value only exists temporarily and never gets saved to the database. By convention, the confirmation property has to be named the same as the property with "Confirmation" appended at the end. Using the password example, to confirm our password property, we would create a property called passwordConfirmation.

Name Type Required Default Description
properties string No Name of property or list of property names to validate against (can also be called with the property argument).
message string No [property] should match confirmation Supply a custom error message here to override the built-in one.
when string No onSave Pass in onCreate or onUpdate to limit when this validation occurs (by default validation will occur on both create and update, i.e. onSave).
condition string No String expression to be evaluated that decides if validation will be run (if the expression returns true validation will run).
unless string No String expression to be evaluated that decides if validation will be run (if the expression returns false validation will run).
caseSensitive boolean No false Ensure the confirmed property comparison is case sensitive
// 1. Require a confirmed password when creating a new user account
// The form should include a `passwordConfirmation` field that the user types their password into a second time
validatesConfirmationOf(property="password", when="onCreate", message="Your password and its confirmation do not match. Please try again.");

// 2. Confirm an email address on every save (default `when="onSave"`)
// A matching `emailConfirmation` property must be set on the object before saving
validatesConfirmationOf(property="email");

// 3. Confirm multiple properties and use a case-sensitive comparison
// Both `passwordConfirmation` and `pinConfirmation` must match exactly (including letter case)
validatesConfirmationOf(properties="password,pin", caseSensitive=true);

validatesExclusionOf()

Model Configuration Validation Functions void model

Validates that the value of the specified property does not exist in the supplied list.

Name Type Required Default Description
properties string No Name of property or list of property names to validate against (can also be called with the property argument).
list string Yes Single value or list of values that should not be allowed.
message string No [property] is reserved Supply a custom error message here to override the built-in one.
when string No onSave Pass in onCreate or onUpdate to limit when this validation occurs (by default validation will occur on both create and update, i.e. onSave).
allowBlank boolean No false If set to true, validation will be skipped if the property value is an empty string or doesn't exist at all. This is useful if you only want to run this validation after it passes the validatesPresenceOf test, thus avoiding duplicate error messages if it doesn't.
condition string No String expression to be evaluated that decides if validation will be run (if the expression returns true validation will run).
unless string No String expression to be evaluated that decides if validation will be run (if the expression returns false validation will run).
// 1. Prevent reserved words from being saved as a programming language name
validatesExclusionOf(property="language", list="php,fortran", message="[property] is reserved. Try a real language.");

// 2. Validate multiple properties against the same exclusion list (e.g. reserved usernames)
validatesExclusionOf(properties="username,displayName", list="admin,root,superuser,moderator");

// 3. Only enforce the exclusion on create, and skip validation when the value is blank
validatesExclusionOf(property="referralCode", list="FREE,GRATIS,FREEBIE", when="onCreate", allowBlank=true);

// 4. Conditionally enforce the exclusion based on a model property
validatesExclusionOf(property="status", list="banned,suspended", condition="this.isAdmin");

validatesFormatOf()

Model Configuration Validation Functions void model

Validates that the value of the specified property is formatted correctly by matching it against a regular expression using the regEx argument and / or against a built-in CFML validation type using the type argument (creditcard, date, email, etc.).

Name Type Required Default Description
properties string No Name of property or list of property names to validate against (can also be called with the property argument).
regEx string No Regular expression to verify against.
type string No One of the following types to verify against: creditcard, date, email, eurodate, guid, social_security_number, ssn, telephone, time, URL, USdate, UUID, variableName, zipcode (will be passed through to your CFML engine's IsValid() function).
message string No [property] is invalid Supply a custom error message here to override the built-in one.
when string No onSave Pass in onCreate or onUpdate to limit when this validation occurs (by default validation will occur on both create and update, i.e. onSave).
allowBlank boolean No false If set to true, validation will be skipped if the property value is an empty string or doesn't exist at all. This is useful if you only want to run this validation after it passes the validatesPresenceOf test, thus avoiding duplicate error messages if it doesn't.
condition string No String expression to be evaluated that decides if validation will be run (if the expression returns true validation will run).
unless string No String expression to be evaluated that decides if validation will be run (if the expression returns false validation will run).
// 1. Validate that a credit card number is in the correct format
validatesFormatOf(property="creditCard", type="creditcard");

// 2. Validate an email address using a regular expression
validatesFormatOf(property="email", type="email");

// 3. Validate a US phone number with a custom regex and allow blank values
validatesFormatOf(
	property="phone",
	regEx="^\d{3}-\d{3}-\d{4}$",
	allowBlank=true,
	message="[property] must be in the format 555-867-5309."
);

// 4. Validate that an email ends with `.se` only when a condition is met and it's not Sunday
validatesFormatOf(
	property="email",
	regEx="^.*@.*\.se$",
	condition="ipCheck()",
	unless="DayOfWeek() eq 1",
	message="Sorry, you must have a Swedish email address to use this website."
);

validatesInclusionOf()

Model Configuration Validation Functions void model

Validates that the value of the specified property exists in the supplied list.

Name Type Required Default Description
properties string No Name of property or list of property names to validate against (can also be called with the property argument).
list string Yes List of allowed values.
message string No [property] is not included in the list Supply a custom error message here to override the built-in one.
when string No onSave Pass in onCreate or onUpdate to limit when this validation occurs (by default validation will occur on both create and update, i.e. onSave).
allowBlank boolean No false If set to true, validation will be skipped if the property value is an empty string or doesn't exist at all. This is useful if you only want to run this validation after it passes the validatesPresenceOf test, thus avoiding duplicate error messages if it doesn't.
condition string No String expression to be evaluated that decides if validation will be run (if the expression returns true validation will run).
unless string No String expression to be evaluated that decides if validation will be run (if the expression returns false validation will run).
// 1. Validate that a user selects a valid framework choice
validatesInclusionOf(property="frameworkOfChoice", list="cfwheels,rails,django", message="Please select a supported framework.");

// 2. Validate a status field and skip validation if the value is blank
validatesInclusionOf(property="status", list="active,inactive,pending", allowBlank=true);

// 3. Validate a role only when creating a new record
validatesInclusionOf(property="role", list="admin,editor,viewer", when="onCreate");

// 4. Validate a priority field only when a condition is met
validatesInclusionOf(property="priority", list="low,medium,high", condition="this.isAssigned()");

validatesLengthOf()

Model Configuration Validation Functions void model

Validates that the value of the specified property matches the length requirements supplied. Use the exactly, maximum, minimum and within arguments to specify the length requirements.

Name Type Required Default Description
properties string No Name of property or list of property names to validate against (can also be called with the property argument).
message string No [property] is the wrong length Supply a custom error message here to override the built-in one.
when string No onSave Pass in onCreate or onUpdate to limit when this validation occurs (by default validation will occur on both create and update, i.e. onSave).
allowBlank boolean No false If set to true, validation will be skipped if the property value is an empty string or doesn't exist at all. This is useful if you only want to run this validation after it passes the validatesPresenceOf test, thus avoiding duplicate error messages if it doesn't.
exactly numeric No 0 The exact length that the property value must be.
maximum numeric No 0 The maximum length that the property value can be.
minimum numeric No 0 The minimum length that the property value can be.
within string No A list of two values (minimum and maximum) that the length of the property value must fall within.
condition string No String expression to be evaluated that decides if validation will be run (if the expression returns true validation will run).
unless string No String expression to be evaluated that decides if validation will be run (if the expression returns false validation will run).
// 1. Validate a maximum length on multiple properties, using [property] in the
// message so the property label is injected dynamically at runtime
validatesLengthOf(
    properties="firstName,lastName",
    maximum=50,
    message="Please shorten your [property] (50 characters max)."
);

// 2. Validate that a password falls within a range of character lengths
validatesLengthOf(
    property="password",
    within="4,20",
    message="The password must be between 4 and 20 characters."
);

// 3. Validate an exact length only on create, skipping blank values
validatesLengthOf(
    property="postalCode",
    exactly=5,
    when="onCreate",
    allowBlank=true,
    message="Postal code must be exactly 5 characters."
);

validatesNumericalityOf()

Model Configuration Validation Functions void model

Validates that the value of the specified property is numeric.

Name Type Required Default Description
properties string No Name of property or list of property names to validate against (can also be called with the property argument).
message string No [property] is not a number Supply a custom error message here to override the built-in one.
when string No onSave Pass in onCreate or onUpdate to limit when this validation occurs (by default validation will occur on both create and update, i.e. onSave).
allowBlank boolean No false If set to true, validation will be skipped if the property value is an empty string or doesn't exist at all. This is useful if you only want to run this validation after it passes the validatesPresenceOf test, thus avoiding duplicate error messages if it doesn't.
onlyInteger boolean No false Specifies whether the property value must be an integer.
condition string No String expression to be evaluated that decides if validation will be run (if the expression returns true validation will run).
unless string No String expression to be evaluated that decides if validation will be run (if the expression returns false validation will run).
odd boolean No
even boolean No
greaterThan numeric No Specifies whether or not the value must be greater than the supplied value.
greaterThanOrEqualTo numeric No Specifies whether or not the value must be greater than or equal the supplied value.
equalTo numeric No Specifies whether or not the value must be equal to the supplied value.
lessThan numeric No Specifies whether or not the value must be less than the supplied value.
lessThanOrEqualTo numeric No Specifies whether or not the value must be less than or equal the supplied value.
// 1. Validate that the `age` property is a number
validatesNumericalityOf(property="age");

// 2. Validate that the `score` property is a whole number (no decimals), allowing blank so that
// records can be saved without a score (resulting in a NULL in the database)
validatesNumericalityOf(property="score", onlyInteger=true, allowBlank=true, message="Please enter a whole number for score.");

// 3. Validate that a `price` value is greater than zero and no more than 10000
validatesNumericalityOf(property="price", greaterThan=0, lessThanOrEqualTo=10000);

// 4. Validate that `quantity` is at least 1, is an integer, and only on create
validatesNumericalityOf(property="quantity", onlyInteger=true, greaterThanOrEqualTo=1, when="onCreate");

// 5. Validate that `rating` must be exactly 5 only when a condition is met
validatesNumericalityOf(property="rating", equalTo=5, condition="this.isPerfect()");

// 6. Validate that `luckyNumber` is an odd number
validatesNumericalityOf(property="luckyNumber", odd=true, message="[property] must be an odd number.");

validatesPresenceOf()

Model Configuration Validation Functions void model

Validates that the specified property exists and that its value is not blank.

Name Type Required Default Description
properties string No Name of property or list of property names to validate against (can also be called with the property argument).
message string No [property] can't be empty Supply a custom error message here to override the built-in one.
when string No onSave Pass in onCreate or onUpdate to limit when this validation occurs (by default validation will occur on both create and update, i.e. onSave).
condition string No String expression to be evaluated that decides if validation will be run (if the expression returns true validation will run).
unless string No String expression to be evaluated that decides if validation will be run (if the expression returns false validation will run).
// 1. Require a single property (must exist and not be blank)
validatesPresenceOf("emailAddress");

// 2. Require multiple properties at once
validatesPresenceOf(properties="firstName,lastName,emailAddress");

// 3. Supply a custom error message
validatesPresenceOf(properties="title", message="A title is required.");

// 4. Only validate on create (skip when updating an existing record)
validatesPresenceOf(properties="password", when="onCreate");

// 5. Conditionally require a property based on another property value
validatesPresenceOf(properties="companyName", condition="this.accountType eq 'business'");

// 6. Skip validation when a certain condition is true
validatesPresenceOf(properties="bio", unless="this.isGuest()");

validatesUniquenessOf()

Model Configuration Validation Functions void model

Validates that the value of the specified property is unique in the database table. Useful for ensuring that two users can't sign up to a website with identical usernames for example. When a new record is created, a check is made to make sure that no record already exists in the database table with the given value for the specified property. When the record is updated, the same check is made but disregarding the record itself.

Name Type Required Default Description
properties string No Name of property or list of property names to validate against (can also be called with the property argument).
message string No [property] has already been taken Supply a custom error message here to override the built-in one.
when string No onSave Pass in onCreate or onUpdate to limit when this validation occurs (by default validation will occur on both create and update, i.e. onSave).
allowBlank boolean No false If set to true, validation will be skipped if the property value is an empty string or doesn't exist at all. This is useful if you only want to run this validation after it passes the validatesPresenceOf test, thus avoiding duplicate error messages if it doesn't.
scope string No One or more properties by which to limit the scope of the uniqueness constraint.
condition string No String expression to be evaluated that decides if validation will be run (if the expression returns true validation will run).
unless string No String expression to be evaluated that decides if validation will be run (if the expression returns false validation will run).
includeSoftDeletes boolean No true Set to true to include soft-deleted records in the queries that this method runs.
// 1. Ensure no two users share the same username
validatesUniquenessOf(property="username", message="Sorry, that username is already taken.");

// 2. Scope uniqueness to an account — the same username is allowed in different accounts
validatesUniquenessOf(property="username", scope="accountId");

// 3. Validate multiple properties for uniqueness in one call
validatesUniquenessOf(properties="email,username");

// 4. Skip the check when the email field is blank (pair with validatesPresenceOf to avoid duplicate errors)
validatesUniquenessOf(property="email", allowBlank=true);

// 5. Only enforce uniqueness on create, not on update
validatesUniquenessOf(property="slug", when="onCreate");

// 6. Run the check only when a condition is true
validatesUniquenessOf(property="referralCode", condition="this.isAffiliate()");

// 7. Exclude soft-deleted records from the uniqueness check so a previously-deleted value can be reused
validatesUniquenessOf(property="username", includeSoftDeletes=false);

validationInfo()

Model Class Miscellaneous Functions struct model

Returns a struct containing all validation rules for this model, keyed by trigger (onSave, onCreate, onUpdate). Each trigger contains an array of validation rule structs with method, properties, message, and other parameters.

// 1. Inspect all validation rules defined on the User model
info = model("User").validationInfo();
// info is keyed by trigger: onSave, onCreate, onUpdate
// Each key holds an array of rule structs, e.g.:
// info.onSave[1] -> {method: "validatesPresenceOf", properties: "email", message: "can't be blank", ...}
// info.onCreate -> []
// info.onUpdate -> []

// 2. Count how many rules fire on every save
info = model("User").validationInfo();
writeOutput("Rules on save: " & arrayLen(info.onSave));

// 3. List the validation methods used across all triggers
info = model("User").validationInfo();
for (trigger in info) {
    for (rule in info[trigger]) {
        writeOutput(trigger & ": " & rule.method & " on " & rule.properties);
    }
}

validationTypeForProperty()

Model Class Miscellaneous Functions any model

Returns the validation type for the property.

Name Type Required Default Description
property string Yes Name of column to retrieve data for.
// 1. Get the validation type for a string column (e.g. firstName is varchar)
type = model("Employee").validationTypeForProperty("firstName");
// type -> "string"

// 2. Get the validation type for a numeric column (e.g. salary is integer)
type = model("Employee").validationTypeForProperty("salary");
// type -> "numeric"

// 3. Get the validation type for a date column (e.g. hireDate is a date/datetime column)
type = model("Employee").validationTypeForProperty("hireDate");
// type -> "date"

// 4. Property does not exist on the model — returns "string" as the default
type = model("Employee").validationTypeForProperty("nonExistentProperty");
// type -> "string"

verificationChain()

Controller Configuration Functions array controller

Returns an array of all the verifications set on this controller in the order in which they will be executed.

// 1. Get verification chain, remove the first item, and set it back.
myVerificationChain = verificationChain();
arrayDeleteAt(myVerificationChain, 1);
setVerificationChain(myVerificationChain);

// 2. Inspect the number of verifications registered on this controller.
chain = verificationChain();
writeOutput("Verifications registered: " & arrayLen(chain));

// 3. Loop over the chain to find verifications that apply to a specific action.
chain = verificationChain();
for (item in chain) {
	if (listFindNoCase(item.only, "create")) {
		writeOutput("Verification applies to create: " & serializeJSON(item));
	}
}

verifies()

Controller Configuration Functions void controller

Instructs Wheels to verify that some specific criteria are met before running an action. Note that all undeclared arguments will be passed to redirectTo() call if a handler is not specified.

Name Type Required Default Description
only string No List of action names to limit this verification to.
except string No List of action names to exclude this verification from.
post any No Set to true to verify that this is a POST request.
get any No Set to true to verify that this is a GET request.
ajax any No Set to true to verify that this is an AJAX request.
cookie string No Verify that the passed in variable name exists in the cookie scope.
session string No Verify that the passed in variable name exists in the session scope.
params string No Verify that the passed in variable name exists in the params struct.
handler string No Pass in the name of a function that should handle failed verifications. The default is to just abort the request when a verification fails.
cookieTypes string No List of types to check each listed cookie value against (will be passed through to your CFML engine's IsValid function).
sessionTypes string No List of types to check each list session value against (will be passed through to your CFML engine's IsValid function).
paramsTypes string No List of types to check each params value against (will be passed through to your CFML engine's IsValid function).
// 1. Verify that the `handleForm` action is always a POST request.
verifies(only="handleForm", post=true);

// 2. Verify that the `edit` action is a GET request, that `userId` exists in `params`, and that it is an integer.
verifies(only="edit", get=true, params="userId", paramsTypes="integer");

// 3. Same as above, but invoke a custom handler function on failure instead of aborting.
verifies(only="edit", get=true, params="userId", paramsTypes="integer", handler="accessDenied");

// 4. Same verification, but redirect to the `index` action with a flash error message on failure.
verifies(only="edit", get=true, params="userId", paramsTypes="integer", action="index", error="Invalid userId");

// 5. Verify that a session variable named `userId` exists for all actions except `login` and `register`.
verifies(except="login,register", session="userId");

// 6. Verify that the `subscribe` action is an AJAX POST request and that `email` exists in `params` as a valid email address.
verifies(only="subscribe", ajax=true, post=true, params="email", paramsTypes="email");

version()

Configuration Routing struct mapper

Scope routes under a version prefix within an API group. Creates a URL path prefix of v{number} (e.g., /api/v1/users) and a name prefix of v{number} for named route generation.

Name Type Required Default Description
number numeric Yes The version number (e.g., 1 creates path prefix v1).
path string No [runtime expression] Override the path prefix. Defaults to v{number}.
name string No [runtime expression] Override the name prefix. Defaults to v{number}.
callback any No A callback function to define nested routes within this version scope.
<cfscript>

// 1. Basic versioned API routes using api() and version() together
mapper()
    .api()
        .version(number=1)
            // Route name:  apiV1Users
            // Example URL: /api/v1/users
            .resources("users")
        .end()

        .version(number=2)
            // Route name:  apiV2Users
            // Example URL: /api/v2/users
            .resources("users")
        .end()
    .end()
.end();

// 2. Using a callback to define routes within the version scope
mapper()
    .api(callback=function(r) {
        r.version(number=1, callback=function(r) {
            // Route name:  apiV1Products
            // Example URL: /api/v1/products
            r.resources("products");
        });
    })
.end();

// 3. Overriding the path and name prefixes
mapper()
    .api()
        .version(number=1, path="version-one", name="versionOne")
            // Route name:  apiVersionOneOrders
            // Example URL: /api/version-one/orders
            .resources("orders")
        .end()
    .end()
.end();

</cfscript>

viteAsset()

View Helpers Asset Functions string controller

Returns the resolved URL for a Vite entrypoint. In production, reads the Vite manifest to return the fingerprinted asset path. In development, returns the Vite dev server URL.

Name Type Required Default Description
entrypoint string Yes The source entrypoint path as defined in your Vite config (e.g. "src/main.js").
// 1. Get the resolved URL for a Vite JS entrypoint
// In production, returns a fingerprinted path like "/dist/assets/main-Dz8C9a3m.js"
// In development, returns the Vite dev server URL like "http://localhost:5173/src/main.js"
assetUrl = viteAsset("src/main.js");

// 2. Use the resolved URL directly in an image or font tag
logoUrl = viteAsset("src/images/logo.png");
writeOutput('<img src="#logoUrl#" alt="Logo">');

// 3. Resolve a CSS entrypoint URL for manual use (e.g. a preload hint)
cssUrl = viteAsset("src/main.css");
writeOutput('<link rel="preload" as="style" href="#cssUrl#">');

vitePreloadTag()

View Helpers Asset Functions string controller

Returns tags for a Vite entrypoint and its transitive chunk imports. Useful for Turbo Drive hover-preload patterns or for explicitly warming assets a subsequent navigation will need. In development mode, returns an empty string — Vite handles module resolution dynamically and modulepreload is unnecessary. emits via $viteHtmlHead() so tags land in .

Name Type Required Default Description
entrypoint string Yes The source entrypoint path (e.g. "src/main.js").
head boolean No true Set to false to return the markup for inline placement; default true
// 1. Emit modulepreload tags into <head> for a JS entrypoint (default behavior)
// In production, injects <link rel="modulepreload"> for the entrypoint and all
// transitive chunk imports into <head>. Returns an empty string.
// In development, returns an empty string (Vite handles modules dynamically).
vitePreloadTag("src/main.js");

// 2. Return modulepreload markup inline instead of injecting into <head>
// Pass head=false to receive the raw HTML for manual placement, for example
// inside a Turbo Drive hover-preload data attribute or a custom <head> partial.
preloadMarkup = vitePreloadTag(entrypoint="src/main.js", head=false);
// preloadMarkup -> '<link rel="modulepreload" href="/dist/assets/main-Dz8C9a3m.js" />\n<link rel="modulepreload" href="/dist/assets/vendor-BpC2d1a0.js" />\n'

// 3. Warm assets for a page the user is likely to navigate to next
// Call from a controller action to preload a separate route's entry module
// so the browser fetches chunks before the user clicks the link.
vitePreloadTag("src/checkout.js");

viteScriptTag()

View Helpers Asset Functions string controller

Returns 'script' tags for a Vite JS entrypoint. In development, also injects the Vite client for Hot Module Replacement (HMR). In production, includes any associated CSS files from the manifest as tags.

Name Type Required Default Description
entrypoint string Yes The source entrypoint path (e.g. "src/main.js").
head boolean No false Set to true to place output in the area instead of inline.
// 1. Emit a script tag for a Vite JS entrypoint inline (default)
// In development, also injects the Vite HMR client.
// In production, emits <link> tags for any associated CSS and a <script type="module"> tag.
writeOutput(viteScriptTag("src/main.js"));

// 2. Place the script tag in the <head> instead of inline
// Passes the generated markup to $htmlHead() so it is buffered into the page <head>.
// Returns an empty string; nothing is printed at the call site.
viteScriptTag(entrypoint="src/main.js", head=true);

// 3. Emit a script tag for a page-specific entrypoint
// Each entrypoint gets its own script tag; CSS chunks discovered in the
// manifest are automatically included as <link rel="stylesheet"> tags.
writeOutput(viteScriptTag("src/checkout.js"));

viteStyleTag()

View Helpers Asset Functions string controller

Returns a tag for a Vite CSS entrypoint. In development, Vite injects CSS via the JS client so this returns an empty string. In production, resolves the fingerprinted path.

Name Type Required Default Description
entrypoint string Yes The source CSS entrypoint path (e.g. "src/main.css").
head boolean No false Set to true to place output in the area instead of inline.
// 1. Emit a <link> tag for a standalone CSS entrypoint inline (default)
// In development, returns an empty string — Vite injects CSS via the HMR JS client.
// In production, outputs a fingerprinted <link rel="stylesheet"> tag.
writeOutput(viteStyleTag("src/main.css"));

// 2. Place the <link> tag in the <head> instead of inline
// Passes the generated markup to $htmlHead() so it is buffered into the page <head>.
// Returns an empty string; nothing is printed at the call site.
viteStyleTag(entrypoint="src/main.css", head=true);

// 3. Emit a <link> tag for a page-specific CSS entrypoint
// Useful when a particular view has its own standalone stylesheet entrypoint
// defined in your Vite config alongside the primary JS bundle.
writeOutput(viteStyleTag("src/checkout.css"));

whereAlpha()

Configuration Routing struct mapper

Constrain a route variable to only match alphabetic characters (a-zA-Z). Similar to Laravel's whereAlpha() or ASP.NET's :alpha constraint.

Name Type Required Default Description
variableName string Yes The route variable name to constrain. Can also be a comma-delimited list.
<cfscript>

mapper()
    // 1. Constrain a single route variable to alphabetic characters only
    //    The [locale] segment will only match values like "en", "fr", "de"
    .get(name="localizedHome", pattern="[locale]/home", to="home##index")
    .whereAlpha("locale")

    // 2. Constrain multiple variables at once using a comma-delimited list
    //    Both [lang] and [region] must contain only a-z / A-Z characters
    .get(name="localizedPage", pattern="[lang]/[region]/[action]", to="pages##show")
    .whereAlpha("lang,region")

    // 3. Chain with other constraint helpers for mixed-type route variables
    //    [category] must be alphabetic; [id] must be numeric
    .resources(name="articles")
    .get(name="articleByCategory", pattern="articles/[category]/[id]", to="articles##byCategory")
    .whereAlpha("category")
    .whereNumber("id")
.end();

</cfscript>

whereAlphaNumeric()

Configuration Routing struct mapper

Constrain a route variable to only match alphanumeric characters (a-zA-Z0-9). Similar to Laravel's whereAlphaNumeric().

Name Type Required Default Description
variableName string Yes The route variable name to constrain. Can also be a comma-delimited list.
<cfscript>

mapper()
    // 1. Constrain a single route variable to alphanumeric characters only
    .get(name="profile", pattern="profiles/[username]", to="profiles##show")
    .whereAlphaNumeric("username")

    // 2. Constrain multiple variables to alphanumeric in one call (comma-delimited list)
    .get(name="teamMember", pattern="teams/[teamCode]/members/[memberCode]", to="teams##member")
    .whereAlphaNumeric("teamCode,memberCode")

    // 3. Chain whereAlphaNumeric with a resources block to restrict the key variable
    .resources(name="products")
    .whereAlphaNumeric("key")
.end();

</cfscript>

whereIn()

Configuration Routing struct mapper

Constrain a route variable to only match one of a set of allowed values. Similar to an enum constraint.

Name Type Required Default Description
variableName string Yes The route variable name to constrain.
values string Yes A comma-delimited list of allowed values (e.g., "active,inactive,pending").
<cfscript>

mapper()
    // 1. Constrain a route variable to a fixed set of allowed string values
    //    The [status] segment will only match "active", "inactive", or "pending"
    .get(name="usersByStatus", pattern="users/[status]", to="users##byStatus")
    .whereIn(variableName="status", values="active,inactive,pending")

    // 2. Constrain a locale segment to a known list of supported languages
    //    Requests like /en/home match; /xx/home returns a 404
    .get(name="localizedHome", pattern="[locale]/home", to="home##index")
    .whereIn(variableName="locale", values="en,fr,de,es")

    // 3. Chain whereIn with whereNumber for mixed-type segment constraints
    //    [type] must be one of the listed values; [id] must be numeric
    .get(name="typedItem", pattern="items/[type]/[id]", to="items##show")
    .whereIn(variableName="type", values="book,magazine,journal")
    .whereNumber("id")
.end();

</cfscript>

whereMatch()

Configuration Routing struct mapper

Constrain a route variable with a custom regex pattern.

Name Type Required Default Description
variableName string Yes The route variable name to constrain.
pattern string Yes The regex pattern the variable must match.
<cfscript>

mapper()
    // 1. Constrain a route variable to a custom regex pattern (year: 4-digit number)
    .get(name="archiveYear", pattern="archive/[year]", to="posts##archiveByYear")
    .whereMatch(variableName="year", pattern="\d{4}")

    // 2. Constrain a slug variable to lowercase letters and hyphens only
    .get(name="articleShow", pattern="articles/[slug]", to="articles##show")
    .whereMatch(variableName="slug", pattern="[a-z][a-z0-9-]+")

    // 3. Chained with resources — constrain the key to a specific format (e.g. SKU like AB-12345)
    .resources("products")
    .whereMatch(variableName="key", pattern="[A-Z]{2}-\d{5}")
.end();

</cfscript>

whereNumber()

Configuration Routing struct mapper

Constrain a route variable to only match numeric values (digits). Similar to Laravel's whereNumber() or ASP.NET's :int constraint.

Name Type Required Default Description
variableName string Yes The route variable name to constrain (e.g., "id"). Can also be a comma-delimited list to constrain multiple variables.
<cfscript>

mapper()
    // 1. Constrain a single route variable to numeric digits only
    //    The [id] segment will only match values like "1", "42", "1000"
    .get(name="article", pattern="articles/[id]", to="articles##show")
    .whereNumber("id")

    // 2. Constrain multiple variables at once using a comma-delimited list
    //    Both [year] and [month] must contain only digit characters
    .get(name="archiveMonth", pattern="archive/[year]/[month]", to="posts##archive")
    .whereNumber("year,month")

    // 3. Chain with other constraint helpers for mixed-type route variables
    //    [category] must be alphabetic; [id] must be numeric
    .get(name="categoryItem", pattern="[category]/[id]", to="items##show")
    .whereAlpha("category")
    .whereNumber("id")
.end();

</cfscript>

whereSlug()

Configuration Routing struct mapper

Constrain a route variable to only match URL-friendly slug values (lowercase alphanumeric and hyphens).

Name Type Required Default Description
variableName string Yes The route variable name to constrain. Can also be a comma-delimited list.
<cfscript>

mapper()
    // 1. Constrain a single slug variable — matches "my-article-title" but not "My Article" or "abc123!"
    .get(name="article", to="articles##show")
    .whereSlug("slug")

    // 2. Chain with another constraint helper after a resource route
    .resources(name="posts")
    .whereSlug("postSlug")

    // 3. Constrain multiple slug variables at once using a comma-delimited list
    .get(name="categoryPost", pattern="[category]/[postSlug]", to="posts##showByCategory")
    .whereSlug("category,postSlug")
.end();

</cfscript>

whereUuid()

Configuration Routing struct mapper

Constrain a route variable to only match UUID values. Similar to ASP.NET's :guid constraint.

Name Type Required Default Description
variableName string Yes The route variable name to constrain. Can also be a comma-delimited list.
<cfscript>

mapper()
    // 1. Constrain a single route variable to UUID values only
    //    The [id] segment will only match values like "550e8400-e29b-41d4-a716-446655440000"
    .get(name="document", pattern="documents/[id]", to="documents##show")
    .whereUuid("id")

    // 2. Constrain multiple variables to UUID format using a comma-delimited list
    //    Both [userId] and [sessionId] must be valid UUID values
    .get(name="userSession", pattern="users/[userId]/sessions/[sessionId]", to="sessions##show")
    .whereUuid("userId,sessionId")

    // 3. Chain with other constraint helpers for mixed-type route variables
    //    [type] must be alphabetic; [id] must be a UUID
    .get(name="typedResource", pattern="resources/[type]/[id]", to="resources##show")
    .whereAlpha("type")
    .whereUuid("id")
.end();

</cfscript>

wildcard()

Configuration Routing struct mapper

Special wildcard matching generates routes with `

Name Type Required Default Description
method string No get List of HTTP methods (verbs) to generate the wildcard routes for. We strongly recommend leaving the default value of get and using other routing mappers if you need to POST to a URL endpoint. Pass an empty string to generate the wildcard routes for all verbs (get, post, put, patch, and delete).
action string No index Default action to specify if the value for the [action] placeholder is not provided.
mapKey boolean No false Whether or not to enable a [key] matcher, enabling a [controller]/[action]/[key] pattern.
mapFormat boolean No false Whether or not to add an optional .[format] pattern to the end of the generated routes. This is useful for providing formats via URL like json, xml, pdf, etc.
methods string No Alias for method, provided for better readability when listing multiple methods. Takes precedence over method when both are passed.
<cfscript>

mapper()
    // 1. Basic wildcard: enables `[controller]` and `[controller]/[action]`
    //    patterns via GET requests only.
    .wildcard()

    // 2. Also enable a `[controller]/[action]/[key]` pattern.
    .wildcard(mapKey=true)

    // 3. Add an optional `.[format]` suffix to every generated pattern,
    //    e.g. `[controller]/[action].json`.
    .wildcard(mapFormat=true)

    // 4. Change the default action when only `[controller]` is matched.
    //    Requests to `/photos` will route to `photos##home` instead of
    //    `photos##index`.
    .wildcard(action="home")

    // 5. Allow additional HTTP methods beyond GET.
    //    Note: opening up extra methods can create security holes unless
    //    you use `verifies` in your controller to guard data-changing actions.
    .wildcard(method="get,post")
.end();

</cfscript>

withAdvisoryLock()

Model Class Locking Functions any model

Executes a callback while holding a database advisory lock. The lock is automatically released when the callback completes, even if an exception is thrown. Advisory locks are database-level locks that don't lock rows or tables. They are useful for coordinating exclusive access to shared resources across application instances. Support varies by database: - PostgreSQL: Full support via pg_advisory_lock/pg_advisory_unlock - MySQL: Full support via GET_LOCK/RELEASE_LOCK - SQL Server: Full support via sp_getapplock/sp_releaseapplock - SQLite: No-op (file-level locking only) - CockroachDB: Not supported (throws error, use forUpdate() instead) - H2: Not supported (throws error) - Oracle: Not supported by default (requires DBMS_LOCK package setup)

Name Type Required Default Description
name string Yes A unique name for the lock. Different callers using the same name will contend for the same lock.
timeout numeric No 10 Maximum number of seconds to wait when acquiring the lock (supported by MySQL and SQL Server).
callback any Yes A function or closure to execute while holding the lock. Its return value is returned by this method.
// 1. Prevent duplicate processing of a background job
model("Job").withAdvisoryLock(name="process-nightly-report", callback=function() {
    job = model("Job").findOneByNameAndStatus(name="nightly-report", status="pending");
    if (isObject(job)) {
        job.process();
    }
});

// 2. Serialize access to a shared external resource with a custom timeout
result = model("Payment").withAdvisoryLock(
    name="payment-gateway-sync",
    timeout=30,
    callback=function() {
        return model("Payment").syncWithGateway();
    }
);

// 3. Ensure only one instance assigns the next batch of records
model("Task").withAdvisoryLock(name="task-batch-assignment", callback=function() {
    tasks = model("Task").findAll(
        conditions="assignedTo IS NULL",
        maxRows=10,
        returnAs="objects"
    );
    for (task in tasks) {
        task.update(assignedTo=getCurrentWorkerID());
    }
});

wordTruncate()

Global Helpers String Functions string controller model mapper migrator migration tabledefinition

Truncates text to the specified length of words and replaces the remaining characters with the specified truncate string (which defaults to "...").

Name Type Required Default Description
text string Yes The text to truncate.
length numeric No 5 Number of words to truncate the text to.
truncateString string No ... String to replace the last characters with.
// 1. Truncate text to the first 4 words (default truncate string "...")
result = wordTruncate(text="CFWheels is a framework for ColdFusion", length=4);
// result -> "CFWheels is a framework..."

// 2. Truncate with a custom truncate string
result = wordTruncate(text="The quick brown fox jumps over the lazy dog", length=5, truncateString=" [read more]");
// result -> "The quick brown fox jumps [read more]"

// 3. Text with fewer words than the limit is returned unchanged
result = wordTruncate(text="Short text", length=10);
// result -> "Short text"

yearSelectTag()

View Helpers Form Tag Functions string controller

Builds and returns a string containing a select form control for a range of years based on the supplied name.

Name Type Required Default Description
name string Yes Name to populate in tag's name attribute.
selected string No The year that should be selected initially.
startYear numeric No 2021 First year in select list.
endYear numeric No 2031 Last year in select list.
includeBlank any No false Whether to include a blank option in the select form control. Pass true to include a blank line or a string that should represent what display text should appear for the empty value (for example, "- Select One -").
label string No The label text to use in the form control.
labelPlacement string No around Whether to place the label before, after, or wrapped around the form control. Label text placement can be controlled using aroundLeft or aroundRight.
prepend string No String to prepend to the form control. Useful to wrap the form control with HTML tags.
append string No String to append to the form control. Useful to wrap the form control with HTML tags.
prependToLabel string No String to prepend to the form control's label. Useful to wrap the form control with HTML tags.
appendToLabel string No String to append to the form control's label. Useful to wrap the form control with HTML tags.
encode any No true Use this argument to decide whether the output of the function should be encoded in order to prevent Cross Site Scripting (XSS) attacks. Set it to true to encode all relevant output for the specific HTML element in question (e.g. tag content, attribute values, and URLs). For HTML elements that have both tag content and attribute values you can set this argument to attributes to only encode attribute values and not tag content.
// 1. Basic year select tag using the current request params as the selected value
#yearSelectTag(name="yearOfBirthday", selected=params.yearOfBirthday)#

// 2. Restrict the range to the past 50 years with a minimum of 18 years ago
#yearSelectTag(
    name="yearOfBirthday",
    selected=params.yearOfBirthday,
    startYear=Year(Now()) - 50,
    endYear=Year(Now()) - 18
)#

// 3. Include a blank prompt and wrap with a label
#yearSelectTag(
    name="yearOfBirthday",
    selected=params.yearOfBirthday,
    includeBlank="- Select Year -",
    label="Birth Year",
    labelPlacement="before"
)#
Wheels 4.0.6

Request Details

Route
wheelsApiDocs
Controller
wheels.Public
Action
api
HTTP Method
GET
URL
admin.alexandreclasquin.com/wheels/api
Application
portfolio-web
Data Source
wheels
URL Rewriting
On

Execution Timing — 45ms total

No timing breakdown available.

Request Parameters

NameValueType
formathtmlstring
typecorestring

Environment & Configuration

Application
Environment
Development — TestingMaintenanceProduction
Wheels Version
4.0.6
CFML Engine
Lucee 7.1.0.204
Host Name
95085416849b
Packages

No packages installed.

Plugins (Legacy)

No plugins installed.