Building expressions
Expressions in Slingr
Expressions in Slingr consist of sets of conditions that can be grouped using AND
and OR
operators. These expressions can be evaluated against a record, resulting in a true
value if the record matches the expression, and false
if it doesn’t.
Moreover, these expressions can be easily translated into database queries, making them particularly useful when you need to retrieve all records that match a specific expression.
While in many cases, expressions can be replaced by scripts (with that option being available when applicable), it is recommended to define your conditions using expressions for several reasons:
Maintainability
: Expressions are automatically refactored whenever fields are modified, eliminating the need for manual adjustments in most instances.Usability
: Expressions can be created using the UI, offering a more intuitive and user-friendly experience.Database queries
: For many scenarios, expressions can be directly applied to the database. In cases where queries are necessary, you won’t be able to use scripts (such as for access permissions).
Expressions are associated with a target entity, which contains the records against which the expression is evaluated. They comprise a set of conditions that can be organized using AND
and OR
groups.
Each filter within an expression has the following attributes:
Target field
: This refers to a field in the target entity that will be filtered, except in cases ofBy user value
.Operator
: Used to filter the field (available operators depend on the field type).Value
: The filtering value, which can be hard-coded (By value
orBy user value
), obtained from a field in a record (By record field
), or taken from a field in the user extended fields record (By user field
).
Complex expressions can be built by combining groups and conditions. For instance, an example expression could look like this:
- AND
- By value: type = 'a'
- OR
- By value: state = 'inactive'
- By value: name like 'test'
Expressions are a versatile concept used in various contexts within the app definition. Paying close attention to the context is essential to understand the target entity and the potential source entity (in conditions of type By record field
).
For instance, consider the following scenarios:
- In a
By value
condition for read/write access in an entity field, the target entity will be the entity housing the field. - If the condition is of type
By record field
in the filter of a relationship field, the target entity will be the entity that the relationship points to, while the source entity will be the entity with the relationship field.
Groups
AND
All elements within an AND
group must evaluate to true
for the group itself to evaluate to true
. If one or more elements within the group evaluate to false
, the entire group will be considered false
. It’s possible to have nested OR
groups inside an AND
group.
OR
For an OR
group to evaluate to true
, at least one element within the group must evaluate to true
. If all elements within the group evaluate to false
, the group will be evaluated as false
. Similar to AND
groups, it’s possible to have nested AND
groups inside an OR
group.
Conditions
Conditions within expressions have the following structure:
Target Field - Operator - Value
For example:
type - Equals - 'a'
The different types of conditions are distinguished by how the `Value` is set. It can be: - Hard-coded (`By value` or `By user value`) - Obtained from a field in a record (`By record field`) - Obtained from a field in the user extended fields record (`By user field`)
Understanding how these conditions work with multi-valued fields or many values is crucial.
- When the target field is single-valued and there are multiple values, if any of the values match the value of the target field, the condition evaluates to
true
. - When the target field is multi-valued and there’s only one value, if that value matches any of the values of the target field, the condition evaluates to
true
. - When the target field is multi-valued and there are multiple values, if any value matches any of the values in the target field, the condition evaluates to
true
.
By value
In this condition type, the value is hard-coded. Depending on the selected operator, you can specify one or more values.
By record field
Here, the value is obtained from a field in a record (the Source field
).
For instance, in configuring filters for a relationship field, you might filter records of the target entity based on the type
field, which should equal the value of the companyType
field in the source record. This dynamic filtering ensures that the results differ from record to record.
By user field
User conditions rely on the User extended fields feature, which must be enabled in the app before using this condition type.
In this case, the value is obtained from the field in the user extended record (the Source field
) of the current user. Thus, these conditions work when there’s a current user with an associated user extended fields record; otherwise, the condition evaluates to false
.
For example, the companies
field in the user extended fields entity could indicate the companies users work for. With a tasks
entity featuring a company
field, you could ensure that users only see tasks for companies they work for by applying a By user field
condition in the permissions.
By user value
This filter combines the characteristics of By user field
and By value
. The value is hard-coded as By value
, but the Target field
belongs to an entity configured in the User extended fields.
Operators
The operation determines how the field is filtered. Available operations depend on the field type defined in field
. Possible operations include:
equals
: Equivalent to anany
condition, tests if any element of the current value is in the filter value.notEquals
: Equivalent to anot in
condition, tests if the current value is not in the filter value.like
: Similar toequals
, but matches partial values.between
: Specifies a range where the current value should lie.greater
: Equivalent to the math operator for number types.greaterOrEquals
: Equivalent to the math operator for number types.less
: Equivalent to the math operator for number types.lessOrEquals
: Equivalent to the math operator for number types.empty
: The current value must benull
or an empty list.notEmpty
: The current value must not benull
and not an empty list.
Query format
Expressions can also be represented in query language, which is useful when passing expressions in scripts. For instance:
// this is a simple query expression where field 'company' should be equals to 'GOOGLE'
{
company: 'GOOGLE'
}
// this query expression is to filter by companies with 'type' in 'a' or 'b',
// or with 'numberOfPeople' greater or equals to 100
{
_or: {
type: ['a', 'b'],
numberOfPeople: 'greaterOrEquals(100)'
}
}
// this query expression is to filter companies by the related company to the logged user
{
name: 'currentUserField(company.name)'
}
The way to map filters is by utilizing the field name
and the value
to filter for. Within the value
section, an operation can be specified. The available operations are contingent on the field type defined in field
. These include:
equals
notEquals
like
between
greater
greaterOrEquals
less
lessOrEquals
empty
notEmpty
currentUserField
For a deeper understanding of the query language and the valid operators, please refer to the documentation on Complex Query Language.