Handling Relationships With SMQL
On the Max platform, the following types of relationships are currently supported by SMQL:
Referential (dynamic and static)
Hierarchical
Master/detail
In this class, method names are determined by the relationship type (such as referential or multiple) and the direction in which the relation is invoked (direct or reverse).
Referential Static and Dynamic/Hierarchical/Master Detail Relationships
Direct
<relationship_source_field_full_identifier>
To directly get only the ID of the target:
_<relationship_source_field_full_identifier>
Example
//In this example the relationship field full identifier is io_relational_field_for_test
def records = Database.query("SELECT io_uuid, io_relational_field_for_test FROM io_relational_child_object_for_test");
def record = records.get(0);
def parentRecord = record.io_relational_field_for_test
def name = parentRecord.io_name
def parentRecordUUID = record._io_relational_field_for_test
Inverse
<source_object_full_identifier>_<relationship_full_identifier>
Examples
def records = Database.query("SELECT io_uuid FROM io_relational_parent_object_for_test");
def record = records.get(0);
def childs = record.io_relational_child_object_for_test_io_relational_relationship_identifier;
To improve code readability, you can define the io_reverse_identifier field of the io_relationship object and use it to identify an inverse relationship. For example, if you set the field to childs:
def records = Database.query("SELECT io_uuid FROM io_relational_parent_object_for_test");
def record = records.get(0);
def childs = record.io_childs;
Multiple Relationships
Direct
<relationship_full_identifier>
Example
def records = Database.query("SELECT io_uuid FROM io_simple_nxn_relation_source");
def record = records.get(0);
def parents = record.io_simple_nxn_relation_identifier
parents[0].io_uuid;
Reverse
<source_object_full_identifier>_<relationship_full_identifier>
Examples
def records = Database.query("SELECT io_uuid FROM io_relational_parent_object_for_test");
def record = records.get(0);
//query childs
def childs = record.io_relational_child_object_for_test_io_relational_relationship_identifier;
//add child
record.io_relational_child_object_for_test_io_relational_relationship_identifier << newChild
To improve code readability, you can define the io_reverse_identifier field of the io_relationship object and use it to identify an inverse relationship. For example, if you set the field to childs:
def records = Database.query("SELECT io_uuid FROM io_relational_parent_object_for_test");
def record = records.get(0);
//query childs
def childs = record.io_childs;
//add child
record.io_childs << newChild
Add Related Records to a Collection of Related Entities
The following example shows how to add records to a collection of related records for multiple relationships.
def event = com.servicemax.core.Database.query('select * from io_event').get(0)
def attendee = com.servicemax.core.Database.querySingleResult("select * from io_contact where io_name = 'System Administrator'")

// relates system to the event
event.io_event_attendees << attendee
Remove Related Records From a Collection of Related Entities
The following example shows how to remove records from a collection of related records for multiple relationships.
* 
The record is not deleted and is only removed from the collection.
def event = com.servicemax.core.Database.query('select * from io_event').get(0)
def attendee = com.servicemax.core.Database.querySingleResult("select * from io_contact where io_name = 'System Administrator'")
// removes system from the event's attendees collection
event.io_event_attendees.remove attendee

// multiple records can be removed from the collection with the method removeAll(Collection<MaxObject> resources)
event.io_event_attendees.removeAll([attendee1, attendee2,....,attendeen])
Referential Dynamic Relationships
Determine Related Record Types
Dynamic relationships can have multiple target objects. You can get related record types in various ways, some of which load records and other that do not.
To load a related record (which requires an extra query):
// Retrieve an event record
def event = com.servicemax.core.Database.query("select * from io_event").get(0)

// Then load (costs an extra query) its 'Related To' related record (dynamic referential field with multiple target objects, i.e. Page, Theme, etc)

event.io_related_to.getClassName() //Returns a string with the related record class name, i.e. "Io_Business_Data_Object"

event.io_related_to.getDefinition().getRecordID() //Returns the unique UUID of the related record type, i.e."397e88ee-1ecd-4f23-873d-3b3d044bc2da"

event.io_related_to.getDefinition().getFullIdentifier() //Returns the unique full identifier of the related record type, i.e. "io_business_data_object"
To load a related record without an extra query:
// Retrieve an event record
def event = com.servicemax.core.Database.query("select * from io_event").get(0)

// The following code does not imply an extra query
event._io_related_to[1] //Returns the unique UUID of the related record type, i.e."397e88ee-1ecd-4f23-873d-3b3d044bc2da"
For more information:
Was this helpful?