Relations

Relations express potential connections between records. Think of a relation as the ability for one record to be associated with another. For example, a Person model in social app could have a Friends relation that represents friendship between two people.

Relation basics

Relations in App Maker are bidirectional. Each direction is called a relation end, and each relation end has two properties:

For example, an HR app could use relations to represent a manager and their team:

With this relation, a manager could have multiple team members, but each team member can only have one manager.

Create and edit relations

Create and edit relations in a model's Relations tab. Click Add New Relation to create a new relation. The creation wizard lets you select both relation ends' names and count and set a target model for one of the ends.

Edit relations by selecting an relation end name from the list below the Add New Relation button. For relations that connect two models, the relation list only displays the relation end name of the opposite model. Using the example above, if Manager and TeamMember were two different models, the Manager relation tab would display a TeamMember relation and vice versa.

Relation end sorting

The Sort By drop-down in the relation editor specifies the field that App Maker should use to sort records of a relation end. The Ascending checkbox specifies the sorting order of records for the relation end. Sorting only applies to relation ends that have a count of many. If you don't specify a sorting preference, the model's data backend determines the sorting order.

Ownership of associated records

You can specify Owner for a model on one end of a relation (subject to some rules). Doing so creates an owner-owned relationship for associated records in the two models:

Only specify an owner model in a relation if owned records shouldn't exist without their owner records, and if you want automatic deletion of records on the owned end of the relation.

Specifying a model as an owner doesn't affect the mechanisms for associating or deleting records.

Example

It might make sense to delete invoice items when an invoice is deleted. With a one-to-many relation between the Invoice and Item models, make the Invoice model the owner. When a user deletes an Invoice record, the app also deletes all owned Item records (records that were associated with the deleted Invoice record).

Note that these are specific instances of items (for example, specific disc drives from inventory), not categories of items (for example, kinds of disc drives that you stock).

Rules

Modify associations with a data binding

There are many ways to change the associations between records through data bindings, but the simplest is to access a relation end as a property of a model datasource's item. In model datasources, relation ends are exposed as record properties, much like fields.

Bind a widget's value to @datasource.item.[relation end name], to let the widget display or change associated records for the currently-selected record. This method is especially useful for dropdown widgets and multiselect boxes, for relation ends with a count of one or many, respectively.

Modify associations with a client script

Modifying associations in client scripts is more difficult than doing it through data bindings. In client scripts, you need to ensure that the appropriate datasource has already loaded the record's associated records. You can do this by specifying prefetch on the datasource, by waiting for the onLoad event of a relation datasource, or by waiting for the onDataLoad event of a widget that uses a relation datasource.

Assuming that associated records are loaded, the following code could be used to associate records with the Manager and TeamMember relation ends in the example above:

var managerRecord = app.datasources.Manager.item;
var teamMemberRecord = app.datasources.TeamMember.item;

// Assign a TeamMember to a Manager.
teamMemberRecord
.Manager = managerRecord;

// Add a TeamMember to a Manager's team:
// first get the manager's current team,
// this will be "null" if the relation isn't loaded.
var team = managerRecord.TeamMember;
// Next, add the TeamMember to it.
team
.push(teamMemberRecord);

Modifying associations with a server script

Modifying associations in server scripts is easier than in client scripts, because you don't have to worry about loading associated records. Access the appropriate record, then use its relation end properties to associate records through the relation:

var managerRecord = app.models.Manager.getRecords(["manager1"]);
var teamMemberRecord = app.models.TeamMember.getRecords(["teamMember1"]);

// Assign a Manager to a TeamMember.
teamMemberRecord
.Manager = managerRecord;

// Add an TeamMember to an Manager's team.
managerRecord
.TeamMember.push(teamMemberRecord);
app
.saveRecords([teamMemberRecord, managerRecord]);

Relation filtering

To filter or sort records by a field in a related model, add the relation name or names followed by a field name. App Maker only supports filtering and sorting for one-to-one and many-to-one relations. For example, to filter a Mother relation by the related records' Age field, use Mother.Age.

You can also apply equals, notEquals, in, and notIn filters on an associated record or record key. For example, to check that a manager's manager is assigned correctly, you could filter by Manager.Manager._key._equals.

Relation filtering is available in Data Binding and Server Scripting.

Further reading