By Ramon Leon - 25 February 2007 under Magritte
When working with Magritte, adding validation rules to descriptions is obvious and simple
descriptionStartDate ^MADateDescription new selectorAccessor: #startDate; label: 'Start Date'; beRequired; addCondition: [:value | value > Date today]; yourself
But adding a validation rule that depends on the values of several fields isn't nearly as obvious and is also something that any decent business object needs quite often. Suppose in addition to the above description we have...
descriptionEndDate ^MADateDescription new selectorAccessor: #endDate; label: 'End Date'; beRequired; addCondition: [:value | value > Date today]; yourself
Suppose we want to enforce the #endDate being after the #startDate. We can't add that rule to the #endDate description because we can't reference the #startDate value. We need to add the rule in a place where we can ensure all single field data exists but before its written to the object from the mementos. We need to add a rule to the objects container description like this...
descriptionContainer ^(super descriptionContainer) addCondition: [:memento | (memento cache at: self descriptionEndDate) > (memento cache at: self descriptionStartDate)] labelled: 'End date must be after start date'; yourself
This simply intercepts the container after it's built, and adds a multi field validation by accessing the potential value of those fields. You get passed the memento for the object, and all the field values are in its cache, keyed by their descriptions. You simply read the values and validate them before they have a chance to be written to the real business object. Multi field validations are a bit more complicated than single field validations at the moment, but this pattern works well.