Automatic Validations Tests

A new feature in the upcoming ColdFusion on Wheels v1.1 is automatic validations. As I am writing documentation, I want to test some of this out to see how it works. Feel free to follow along.

Prerequisite: Database Migration Script

First, I generated a migration script using the DBMigrate plugin. This particular migration creates a table called automaticvalidationtests:

1component extends="plugins.dbmigrate.Migration" hint="Creates automaticValidationTests table" {
2
3    //-----------------------------------------------------
4    // Public
5    
6    public function up() {
7        local.t = createTable(name="automaticvalidationtests", force=true);
8        local.t.string(columnNames="name", limit=50, null=false);
9        local.t.string(columnNames="nullname", limit=50, null=true);
10        local.t.integer(columnNames="numbervalue", null=false);
11        local.t.integer(columnNames="nullnumbervalue", null=true);
12        local.t.date(columnNames="datevalue", null=false);
13        local.t.date(columnNames="nulldatevalue", null=true);
14        local.t.create();
15    }
16    
17    //-----------------------------------------------------
18    
19    public function down() {
20        dropTable("automaticvalidationtests");
21    }
22    
23    //-----------------------------------------------------
24
25}

Feel free to read through this script to see what columns I added to the database and their individual settings.

Attempting to Save a Blank Object

Next, I'm running this code, which attempts to save a blank instance of automaticValidationTest. The call to save() will return false.

1// Blank object
2automaticBlank = model("automaticValidationTest").new();
3automaticBlank.save();

And here is a listing of errors generated by #errorMessagesFor("automaticBlank")#:

  • Name can't be empty
  • Numbervalue can't be empty
  • Datevalue can't be empty

This is pretty cool because my model did the following without my needing to write a single line of code in the model:

Attempting to Save Incorrect Formats

Here is some code that will produce invalid formats for the date and int fields:

1// Invalid formats
2automaticInvalidFormats = model("automaticValidationTest").new();
3automaticInvalidFormats.name = "Chris Peters";
4automaticInvalidFormats.nullName = automaticInvalidFormats.name;
5automaticInvalidFormats.numberValue = "I am not a number";
6automaticInvalidFormats.nullNumberValue = automaticInvalidFormats.numberValue;
7automaticInvalidFormats.dateValue = "I am not a date";
8automaticInvalidFormats.nullDateValue = automaticInvalidFormats.dateValue;
9automaticInvalidFormats.save();

Again, here is the output of #errorMessagesFor("automaticInvalidFormats")#:

  • Numbervalue is not a number
  • Nullnumbervalue is not a number
  • Datevalue is invalid
  • Nulldatevalue is invalid

This time, because values were actually provided for numberValue, nullNumberValue and dateValue, and nullDateValue, Wheels performed these checks automatically:

This removes the need for a tremendous amount of configuration from your model files when you consider how many times these validations would otherwise need to be called across an entire application.

Attempting to Save Incorrect Lengths

Because my database schema defines the name and nullName values as varchar(50), Wheels automatic validations will run validatesLengthOf().

Here is some code that defines data with an invalid length:

1// Invalid lengths
2automaticInvalidLength = model("automaticValidationsTest").new();
3automaticInvalidLength.name = "123456789 123456789 123456789 123456789 123456789 1";
4automaticInvalidLength.nullName = "123456789 123456789 123456789 123456789 123456789 1";
5automaticInvalidLength.numberValue = 29;
6automaticInvalidLength.dateValue = Now();
7automaticInvalidLength.save();

And here is the output of its corresponding #errorMessagesFor("automaticInvalidLength")#:

  • Name is the wrong length
  • Nullname is the wrong length

This proves that Wheels adds yet another type of validation that will be run without your needing to write a single line of code. If a maximum allowed length is set it your database, why should you need to repeat that in your application code?

Passing Validation

I can't let this story end on a negative note, so here is a call to save() that passes validation:

1// Passed validation
2automaticPassed = model("automaticValidationTest").new();
3automaticPassed.name = "Chris Peters";
4automaticPassed.numberValue = 29;
5automaticPassed.dateValue = Now();
6result = automaticPassed.save(transaction="rollback");

And here is output of local.result, which is exactly what we want:

true

Credit Where Credit Is Due

Kudos to Andy Bellenie for implementing this wonderful feature that pulls info from the database so that we don't need to type it in anymore!