Skip to content

Commit

Permalink
Rewrite $this parameter usage in DEFINE FIELD
Browse files Browse the repository at this point in the history
  • Loading branch information
Dhghomon committed Oct 17, 2024
1 parent 7904cbd commit 5226249
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 7 deletions.
70 changes: 67 additions & 3 deletions src/content/doc-surrealql/statements/define/field.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -321,19 +321,83 @@ DEFINE FIELD countrycode ON user TYPE string

## Interacting with other fields of the same record

While a `DEFINE TABLE` statement represents a template for any subsequent records to be created, a `DEFINE FIELD` statement pertains to concrete field data of a record. As such, access to both the field itself and its parent record are granted inside `DEFINE FIELD` through the [`$value`](/docs/surrealql/parameters#value) and [`$this`](/docs/surrealql/parameters#parent-this) parameters, respectively.
While a `DEFINE TABLE` statement represents a template for any subsequent records to be created, a `DEFINE FIELD` statement pertains to concrete field data of a record. As such, a `DEFINE FIELD` statement gives access to the record's other fields through their names, as well as the current field through the [`$value`](/docs/surrealql/parameters#value) parameter.

```surql
DEFINE TABLE person SCHEMAFULL;
DEFINE FIELD first_name ON TABLE person TYPE string VALUE string::lowercase($value);
DEFINE FIELD last_name ON TABLE person TYPE string VALUE string::lowercase($value);
DEFINE FIELD name ON TABLE person VALUE $this.first_name + ' ' + $this.last_name;
DEFINE FIELD name ON TABLE person VALUE first_name + ' ' + last_name;
// Creates a `person` with the name "bob bobson"
CREATE person SET first_name = "BOB", last_name = "BOBSON";
```

The `$this` parameter gives access to the entire record on which a field is defined.

```surql
DEFINE FIELD extra_self ON TABLE person VALUE $this;
CREATE person:one SET name = "Little person", age = 6;
```

```surql title="Output"
[
{
age: 6,
extra_self: {
age: 6,
id: person:one,
name: 'Person'
},
id: person:one,
name: 'Person'
}
]
```

In practice, using `$this` to access the full record is useful when a field is defined as an expression, especially a [future](/docs/surrealql/datamodel/futures) which is computed every time the field is accessed.

```surql
DEFINE FIELD followers
ON TABLE person
VALUE <future> { (SELECT VALUE <-follows<-person.id FROM ONLY $this) };
CREATE person:one, person:two, person:three;
RELATE person:one->follows->person:three;
SELECT * FROM person:three;
RELATE person:two->follows->person:three;
SELECT * FROM person:three;
```

```surql title="Output of SELECT statements"
-------- Query --------
[
{
followers: [
person:one
],
id: person:three
}
]
-------- Query --------
[
{
followers: [
person:one,
person:two
],
id: person:three
}
]
```

## Order of operations when setting a field's value

As `DEFINE FIELD` statements are computed in alphabetical order, be sure to keep this in mind when using fields that rely on the values of others.

The following example is identical to the above except that `full_name` has been chosen for the previous field `name`. The `full_name` field will be calculated after `first_name`, but before `last_name`.
Expand All @@ -343,7 +407,7 @@ DEFINE TABLE person SCHEMAFULL;
DEFINE FIELD first_name ON TABLE person TYPE string VALUE string::lowercase($value);
DEFINE FIELD last_name ON TABLE person TYPE string VALUE string::lowercase($value);
DEFINE FIELD full_name ON TABLE person VALUE $this.first_name + ' ' + $this.last_name;
DEFINE FIELD full_name ON TABLE person VALUE first_name + ' ' + last_name;
// Creates a `person` with `full_name` of "bob BOBSON", not "bob bobson"
CREATE person SET first_name = "Bob", last_name = "Bobson";
Expand Down
4 changes: 2 additions & 2 deletions src/content/doc-surrealql/statements/define/table.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -225,14 +225,14 @@ CREATE user SET firstName = 'Jamie', lastName = 'Hitchcock', email = 'Jamie.Hitc

## Interaction between fields

While a `DEFINE TABLE` statement represents a template for any subsequent records to be created, a `DEFINE FIELD` statement pertains to concrete field data of a record. As such, access to both the field itself and its parent record are granted inside `DEFINE FIELD` through the `$value` and `$this` parameters, respectively.
While a `DEFINE TABLE` statement represents a template for any subsequent records to be created, a `DEFINE FIELD` statement pertains to concrete field data of a record. As such, a `DEFINE FIELD` statement gives access to the record's other fields through their names, as well as the current field through the [`$value`](/docs/surrealql/parameters#value) parameter.

```surql
DEFINE TABLE person SCHEMAFULL;
DEFINE FIELD first_name ON TABLE person TYPE string ASSERT string::len($value) < 20;
DEFINE FIELD last_name ON TABLE person TYPE string ASSERT string::len($value) < 20;
DEFINE FIELD name ON TABLE person VALUE $this.first_name + ' ' + $this.last_name;
DEFINE FIELD name ON TABLE person VALUE first_name + ' ' + last_name;
// Creates a `person` with the name "Bob Bobson"
CREATE person SET first_name = "Bob", last_name = "Bobson";
Expand Down
4 changes: 2 additions & 2 deletions src/content/doc-surrealql/statements/relate.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -393,10 +393,10 @@ SELECT id, array::complement(<->sister_of<->city, [id]) AS sister_cities FROM ci
]
```

When using `RELATE` for this sort of relationship, you may want to define a unique key based on the ordered record IDs involved.
When using `RELATE` for this sort of relationship, you may want to [define a field](/docs/surrealql/statements/define/field) as a unique key based on the ordered record IDs involved.

```surql
DEFINE FIELD key ON TABLE sister_of VALUE <string>array::sort([$this.in, $this.out]);
DEFINE FIELD key ON TABLE sister_of VALUE <string>array::sort([in, out]);
DEFINE INDEX only_one_sister_city ON TABLE sister_of FIELDS key UNIQUE;
```

Expand Down

0 comments on commit 5226249

Please sign in to comment.