I had a pretty interesting task recently. We have profiles that must implement certain constraints depending on what kind of profile / product the client purchased. So a profile can have a specific number of languages depending on the constraints. This means we need to validate the number of languages an user has picked by a value from another database table that needs to be picked up somehow at runtime.

Why a validation rule won’t can’t do the job

Validation rules are stateless. They are intended to operate in a stateless way. They are best leveraged to ensure that the shape, data types and format of data is correct.

Application rules are stateful, so they are best leveraged to check stateful properties of your entities. For example, validation rules could ensure that an email address is valid, while an application rule could ensure that the email address is unique.

When validation rules are applied the entity has not yet been marshalled, in other words the entity has not yet really been constructed and processed, the data is still a simple array.

So when you inspect the $context, the 2nd arg of a validation rule, you’ll notice that the `data` key of the array just contains what you’ve passed, but not the whole entity!

Application rules will do it

An application rule will run after the entity object was built by the marshaller and you’ll have all data available you need that was passed and merged if you used patchEntity() for example.

See the “Creating custom rule objects” section of the official documentation on how to create your own rule objects.

Conclusion

Application rules are a nice thing to work with in CakePHP3 even the fact they might not be that easy to understand by a first quick look. You can implement more complex requirements that require you to work on the DB level to validate the integrity of your requirement and database as application rules.