Object Validation
Wheels utilizes validation setup within the model to enforce appropriate data constraints and persistence. Validation may be performed for saves, creates, and updates.
Basic Setup
In order to establish the full cycle of validation, 3 elements need to be in place:
Model file containing business logic for the database table. Example:
models/User.cfc
Controller file for creating, saving or updating a model instance. Example:
controllers/Users.cfc
View file for displaying the original data inputs and an error list. Example:
views/users/index.cfm
Note: Saving, creating, and updating model objects can also be done from the model file itself (or even in the view file if you want to veer completely off into the wild). But to keep things simple, all examples in this chapter will revolve around code in the controller files.
The Model
Validations are always defined in the config()
method of your model. This keeps everything nice and tidy because another developer can check config()
to get a quick idea on how your model behaves.
Let's dive right into a somewhat comprehensive example:
This is fairly readable on its own, but this example defines the following rules that will be run before a create, update, or save is called:
The
firstName
,lastName
,email
,age
, andpassword
fields must be provided, and they can't be blank.At maximum,
firstName
andlastName
can each be up to 50 characters long.The value provided for
email
cannot already be used in the database.The value for
age
can only be an integer.password
must be provided twice, the second time via a field calledpasswordConfirmation
.
If any of these validations fail, Wheels will not commit the create or update to the database. As you'll see later in this chapter, the controller should check for this and react accordingly by showing error messages generated by the model.
Listing of Validation Functions
Automatic Validations
Now that you have a good understanding of how validations work in the model, here is a piece of good news. By default, Wheels will perform many of these validations for you based on how you have your fields set up in the database.
By default, these validations will run without your needing to set up anything in the model:
Date or time fields will be checked for the appropriate format.
Note these extra behaviors as well:
If you've already set a validation on a particular property in your model, the automatic validations will be overridden by your settings.
To disable automatic validations in your Wheels application, change this setting in config/settings.cfm:
Use when, condition, or unless to Limit the Scope of Validation
If you want to limit the scope of the validation, you have 3 arguments at your disposal: when
, condition
, and unless
.
when Argument
The when
argument accepts 3 possible values.
onSave
(the default)onCreate
onUpdate
To limit our email validation to run only on create, we would change that line to this:
condition and unless Arguments
condition
and unless
provide even more flexibility when the when
argument isn't specific enough for your validation's needs.
Each argument accepts a string containing an expression to evaluate. condition
specifies when the validation should be run. unless
specifies when the validation should not be run.
As an example, let's say that the model should only verify a CAPTCHA if the user is logged out, but not when they enter their name as "Ben Forta":
Custom Validations
There is only one difference between how the different functions work:
To use a custom validation, we pass one of these functions a method or set of methods to run:
Note that IsValid()
is a function build into your CFML engine.
This is a simple rule, but you can surmise that this functionality can be used to do more complex validations as well. It's a great way to isolate complex validation rules into separate methods of your model.
Adding Errors to the Model Object as a Whole
As an example, here's a custom validation method that doesn't allow the user to sign up for an account between the hours of 3:00 and 4:00 am in the server's time zone:
Sure, we could add logic to the view to also not show the registration form, but this validation in the model would make sure that data couldn't be posted via a script between those hours as well. Better safe than sorry if you're running a public-facing application!
The Controller
The controller continues with the simplicity of validation setup, and at the most basic level requires only 5 lines of code to persist the form data or return to the original form page to display the list of errors.
The first line of the action creates a newUser
based on the user
model and the form inputs (via the params
struct).
The View
Wheels factors out much of the error display code that you'll ever need. As you can see by this quick example, it appears to mainly be a normal form. But when there are errors in the provided model, Wheels will apply styles to the erroneous fields.
Error Messages
For your reference, here are the default error message formats for the different validation functions:
validatesConfirmationOf()
[property] should match confirmation
validatesExclusionOf()
[property] is reserved
validatesFormatOf()
[property] is invalid
validatesInclusionOf()
[property] is not included in the list
validatesLengthOf()
[property] is the wrong length
validatesNumericalityOf()
[property] is not a number
validatesPresenceOf()
[property] can't be empty
validatesUniquenessOf()
[property] has already been taken
Custom Error Messages
Wheels models provide a set of sensible defaults for validation errors. But sometimes you may want to show something different than the default.
There are 2 ways to accomplish this: through global defaults in your config files or on a per-property basis.
Setting Global Defaults for Error Messages
Using basic global defaults for the validation functions, you can set error messages in your config file at config/settings.cfm
.
As you can see, you can inject the property's name by adding [property]
to the message string. Wheels will automatically separate words based on your camelCasing of the variable names.
Setting an Error Message for a Specific Model Property
Another way of adding a custom error message is by going into an individual property in the model and adding an argument named message
.
Here's a change that we may apply in the config()
method of our model:
Last updated
Was this helpful?