- REDIRECT Training:Constraints
Constraints
Use constraints to define class-level business rules in your MDriven model and show users when an object does not meet those rules.
What a constraint is
A constraint is a rule on a class. Its OCL expression must evaluate to true for the constraint to be valid. When the expression evaluates to false, the constraint is broken.
For example, a Car can require a related Brand. The constraint expression checks that the Brand relation is not empty. A Car without a Brand breaks the constraint; assigning a Brand makes the constraint valid again.
MDriven also has implicit constraints from association-end cardinalities. For example, if an association end has cardinality 1..4, an object with zero related objects at that end has a broken constraint.
Define a class constraint
Define a constraint on the class that owns the business rule. Give the constraint a name, a description for the user, an OCL expression, and an error level.
| Setting | Purpose | Example |
|---|---|---|
| Name | Identifies the rule. | MustHaveBrand
|
| Description | Explains the broken rule to the user. | Car should have a brand
|
| OCL expression | Defines when the rule is valid. It must return a Boolean value. | The expression checks that the Car's Brand relation is not empty. |
| Error level | Determines whether a broken constraint is shown as Information, Warning, or Error. | Use Warning when the user should be informed but the rule is not an error. |
You can use <asString> in a constraint description to include the broken object's string representation. For example, when a Car has its registration number as its string representation, a broken constraint message can identify that Car by its registration number.
How constraints are enforced
MDriven evaluates the constraint expression for the object. A true result means that the constraint is not broken. A false result means that the constraint is broken and its description and error level are available to the user interface.
Constraints automatically appear in ViewModels. When a user corrects the data that caused the rule to break, the broken constraint is removed from the ViewModel presentation. You can opt out an individual constraint for a specific ViewModel when that class-wide message does not apply in that view.
For example, the MustHaveBrand constraint can appear while editing a Car, but you can opt it out from an All Cars ViewModel if that message is not relevant there.
Use constraints in OCL
Use constraints when you need both constraint metadata and its current broken state. Each returned item includes the constraint name, description, delete-constraint status, error level, and broken state.
The following expression checks that no Error-level constraints are broken:
self.constraints->select(c|(c.ErrorLevel = #Error) and c.Broken)->isEmpty
Use brokenConstraints when you only need the names of broken constraints. For example:
Complaint.allinstances->first.brokenConstraints
This returns the violated constraint names for one Complaint instance. For ViewModel-specific validation rules, see Documentation:ViewModel validations.
Use a constraint as a state-machine guard
A GuardConstraint associates one or more class constraints with a state-machine transition. This lets you define a rule once on the class and reuse it for multiple transitions.
For example, add MustHaveBrand to a transition guard. The transition remains disabled while the Car has no Brand. When the user assigns a Brand and the constraint is no longer broken, the transition can become available. Constraint descriptions also give users a reason why a transition is disabled.
Protect deletion with delete constraints
Mark a constraint as a delete constraint when it applies only when an object is deleted. Delete constraints are checked when an object is deleted by MDriven, and the Delete operator is executed on the class.
For example, a Car can have a delete constraint that prevents deletion while it has a deposit unless the Car is in the Scrapped state. This keeps the deletion rule in the model.
Delete processing also checks Business Delete Rules on association ends. Choose the appropriate rule for each association end. For example, set an association end to MustBeEmpty when deleting a Brand must not leave Cars in its AllCarsOfThisBrand association. Use NeedNotBeEmptyNoWarning when deleting a Car is acceptable even when it has a Brand.
