You can add an object through an association class and immediately set attributes on the generated link object; this page is for MDriven Designer developers writing OCL or EAL expressions.
Add an object and reach its link object
An association class represents information about a relationship. For example, a Booking association class can connect a Person and a Flight while holding booking-specific attributes.
When you add a flight to a person's Flights association, MDriven creates the corresponding Booking object. You do not explicitly create the Booking; its lifetime is controlled by the association:
- Adding
aFlighttoself.Flightscreates the booking. - Removing
aFlightfromself.Flightsremoves the corresponding booking. - The same personâflight pair is unique in the association. You cannot add that pair twice.
For the association-class concepts and modeling rules, see Training:Association classes. For general association navigation, see Documentation:Association.
Recommended pattern: addReturnIndexOf0
Use addReturnIndexOf0 when you need the generated link object immediately. The operator adds an object like add, then returns the zero-based index where the added object was placed.
In an association with these navigation names:
| From object | Navigation name | Result |
|---|---|---|
Person
|
Flights
|
A collection of related Flight objects
|
Person
|
Bookings
|
A collection of generated Booking link objects
|
use the returned index to select the corresponding booking:
self.Bookings.at0(self.Flights.addReturnIndexOf0(aFlight)).AttributeOnBookingThis expression performs the following work:
- Adds
aFlighttoself.Flights. - Receives the zero-based position of the added flight.
- Uses
at0with that position inself.Bookings. - Returns
AttributeOnBookingfrom the generatedBooking.
You can assign a value to an attribute on the generated booking in the same expression:
self.Bookings.at0(self.Flights.addReturnIndexOf0(aFlight)).AttributeOnBooking := 'Yes'The index works because the added object and its generated link object have corresponding positions in their respective association-role collections.
Create and configure in one expression
When the object at the other end is created as part of the operation, use a let expression to keep the added object available by name:
let aFlight = Flight.Create in
(
self.Bookings.at0(self.Flights.addReturnIndexOf0(aFlight)).AttributeOnBooking := 'Yes'
)addReturnIndexOf0 and at0 are explicitly zero-based. This differs from ordinary OCL indexing conventions. An at0 lookup with no matching index returns -1, so use the returned index directly rather than calculating an index yourself.
Alternative pattern: find the link object after add
You can add the related object and then select the booking that points to it:
self.Flights.add(aFlight);
self.Bookings->select(b | b.Flight = aFlight)->firstThis pattern is useful when you need to express the lookup by the related object. When the add and link-object access belong to the same operation, prefer addReturnIndexOf0: it identifies the generated link object directly instead of searching the booking collection.
Set meaningful names for both the LinkRoleName and the InnerLinkName on each association end. Clear names make expressions, generated user interfaces, and debugging easier to understand.
| Name | Navigation direction | Example from the Person end |
|---|---|---|
| LinkRoleName | From an endpoint class to the association-class objects | Bookings: from Person to its Booking objects
|
| InnerLinkName | From the association-class object onwards to the opposite endpoint | Flight: from a Booking to its one Flight
|
Choose names that match the cardinality at the navigation point:
- Use a plural name such as
Bookingswhen aPersoncan have many booking objects. - Use a singular name such as
PersonorFlightwhen oneBookingpoints to one object at that end.
For example, a booking is associated with one person, so the navigation name from Booking is Person, not Persons.
Example: set data on a new booking
Assume a person is booking a selected flight and the Booking association class has an attribute named AttributeOnBooking. Put the following expression in an operation on Person:
self.Bookings.at0(self.Flights.addReturnIndexOf0(aFlight)).AttributeOnBooking := 'Yes'After the expression runs:
aFlightis included in the person'sFlightsassociation.- MDriven has created the related
Bookinglink object. AttributeOnBookingon that exact booking is set to'Yes'.
