Docs‎ > ‎CA Live API Creator‎ > ‎Rules‎ > ‎

Validation

Validations are expressions assigned to a table, that must be true for a transaction to commit.  They can reference other columns in the row as row.attribute, as well as parent columns.   They are specified using JavaScript notation.

Whenever the validation's table is altered - either directly by the client or through logic chaining - the system verifies that the result values still meet the validation.  This is reactive programming.  Contrast this with imperative programming, where such dependency management often accounts for substantial code to detect changes and update dependent data.




For example, altering a Line Item may adjust the Purchase Orders amount_total, which adjusts the Customer's balance.  Such derivations are always subjected to validation checks at each level.  So, our transaction might fail due to the following validation:

Validation Customer.CheckCredit as
    return row.balance < row.credit_limit
    with Message(Balance {balance} exceeds credit}

Failed transactions are rolled back, and a suitable message is returned to the client.

Validations can reference all attributes of the current row, their old values, and parent columns.  Changes to parent columns referenced in child logic cascade to all children, so the validation can be rechecked.

It is a best practice for validations to reference derivation results, such as the example described below in Commit Validations.


Attribute references: row, oldRow

Validations are defined for a table, and can reference any column of that table via the row variable as shown above.

Validations can also reference old values via oldRow, so you can specify:

return 100 * (row.total - oldRow.total) / row.total;


Parent References

Validations can also reference Parent attributes (one side of a one-to-many relationship).  To reference parent data, use the dot-notation reference to the parent role/attribute.   See here for important information about Role Names.

The database commands required to access parent data are automated.  This reduces coding, and helps ensure good performance by automatic caching.

For example, you might ensure orders are not altered for customers on hold:

return ! (logicContext.verb == "INSERT" && row.customer.isOnHold == false);


Child Cascade is automated, so that changes in such parent columns are cascaded to each related child row.

You can reference parent data without cascade by using a Parent Copy.

For Transaction update logic

Parent references are provided for transactional update logic, not for retrieval.

You do not need to define new child columns derived from parent columns for retrieval.  It is a Best Practice to use Parent Sub Resources that optimize database and network traffic.


If/Else

Validations can be conditional.  Per use of JavaScript, you can use if / else statements:

if (row.total > 100) {
   return 5;
} else {
   return 3;
}

You can also use ternary expressions as shown below:

return row.total > 100 ? 5 : 3;


Null Handling

References to null attributes in expressions are treated specially to reduce null pointer exceptions, as follows:
parent - if a child references a missing optional parent role name, the value is returned as null.  So, Employee logic can refer to onLoanDepartment, which returns null if the foreign key is null
parent.attribute - is null if no parent.  If the parent exists, it is treated as described below for attribute references
attribute - to simplify null checking,
  • null numeric attributes are returned as 0
  • null string attributes are returned as the empty string 

Context, Logic Context

Most Validations are simple expressions, perhaps with conditional logic as shown above.   But you are not restricted - you can employ the full power of server-side JavaScript.

So, in addition to the row and oldRow supplied variables, the system also supplies additional context, including logicContext.  This provides access to database services and other utility functions your logic may require.

Error Message

The Error Message is the text in the exception returned to the client if the validation evaluates to false. The error message can be up to 2,000 characters long, and you can embed data values, signified by {} brackets. The data values consist of the name of a column, or of a parent column.

In addition, numeric and date values can be formatted using a format string specified after a vertical bar.

For instance, the following error message:

Customer {name}'s balance: {balance|#,##0.00} exceeded their credit limit: {customer_credit.credit_limit | #,##0.00} which is effective as of {customer_credit.effective_date | MM/dd/yy HH:mm}.

would result in the following message being sent back to the client if the validation is violated:

Customer BigCorp's balance: 23,456.78 exceeded their credit limit: 20,000.00 which is effective as of 06/11/13 09:56.

The formatting strings use the standard formatting conventions.


Problem Attributes

The Error Attributes are included in the exception returned to the client if the validation evaluates to false.  Your client can use these to aid in the user interface for error handling (e.g., position the cursor, highlight, etc).


Commit Validations

You can define a validation so that it is checked only at the end of the transaction, when all the logic has been executed for all the rows in the transaction.  See the No Empty Orders example.