# UPDATE statement · Mastering Rell · Learn Chromia

> You can only change an attribute's value if it is declared with mutable:

Source: https://chromia.com/learn/rell-masterclass/update/

Mastering RellLesson 8 of 8

1. [01Mastering Rell](https://chromia.com/learn/rell-masterclass/introduction/)
2. [02Comparing SQL tables and Rell entities](https://chromia.com/learn/rell-masterclass/entities/)
3. [03Code optimization example](https://chromia.com/learn/rell-masterclass/example/)
4. [04Keys and indexes](https://chromia.com/learn/rell-masterclass/indexes/)
5. [05INNER JOIN statement](https://chromia.com/learn/rell-masterclass/join/)
6. [06SELECT statement](https://chromia.com/learn/rell-masterclass/select/)
7. [07Subqueries](https://chromia.com/learn/rell-masterclass/sub-queries/)
8. [08UPDATE statement](https://chromia.com/learn/rell-masterclass/update/)

[Learn](https://chromia.com/learn/)[Mastering Rell](https://chromia.com/learn/rell-masterclass/)

08 / 08

# UPDATE statement

You can only change an attribute's value if it is declared with `mutable`:

rell

```
entity my_entity {
    key my_key: text;
    mutable my_mutable: text;
}
```

Once you hold a reference to an entity, you update an attribute with a plain assignment:

rell

```nolines
my_entity_instance.my_mutable = "new value";
```

Rell translates this into the following SQL:

sql

```nolines
UPDATE "c0.my_entity" A00 SET "my_mutable" = ? WHERE A00."rowid" = ?
```

When several mutable attributes need new values, assigning each one separately costs a database roundtrip per assignment. Use Rell's `update` keyword instead. Its syntax resembles the [at-operator](https://chromia.com/learn/rell-masterclass/select/):

rell

```nolines
FROM        CARDINALITY  WHERE         WHAT
update entity_name @            { condition } ( .my_mutable = "new value" );
```

An assignment takes the place of the *WHAT* part, and there is no *TAIL* part.

This updates multiple fields in one roundtrip. If you already have a reference to the entity, use `$ == entity_instance` as the condition.

## Example

Consider the following code:

rell

```
entity user_info {
    key name;
    key pubkey;
    mutable address: text;
}

operation update_address(name, new_address: text) {
    val user = find_and_check_signer(name);
    user.address = new_address;
}

function find_and_check_signer(name): user_info {
    val user_pubkey = user_info @ { name } (user = $, pubkey = .pubkey);
    require(op_context.is_signer(user_pubkey.pubkey), "User must sign operation");
    return user_pubkey.user;
}
```

The user entity has a name that serves as a unique key, a public key, and a mutable address. The `update_address` operation looks up the user and changes the address. In its first at-expression, `find_and_check_signer` fetches the user entity with the given name together with its `pubkey` property. Having the key already loaded means the function can require a matching signature without running a second SQL select. A simple assignment then sets the new address.

Now suppose the address should be stored as a street name and a zip code. The model changes to:

rell

```
entity user_info {
    key name;
    key pubkey;
    mutable street_address: text;
    mutable zip_code: integer;
}
```

The operation becomes:

rell

```
operation update_address(name, new_street_address: text, new_zip_code: integer) {
    val verified_user = find_and_check_signer(name);
    update user_info @ { $ == verified_user } (
       .street_address = new_street_address,
       .zip_code = new_zip_code
    );
}
```

Both attributes are now updated together.

tip

Where possible, combine the `update` operation with `{ $ == <instance> }` so that several attributes change in a single database roundtrip.

## Practical example

The following walkthrough creates a user, updates that user, and checks the updated data against the user's public key.

In the `src/main` directory, add the `user_info` entity to `entities.rell`:

src/main/entities.rell

```
entity user_info {
    key name;
    key pubkey;
    mutable street_address: text;
    mutable zip_code: integer;
}
```

Add the `find_and_check_signer` function to `src/main/functions.rell`. It verifies the user's public key:

src/main/functions.rell

```
function find_and_check_signer(name): user_info {
    val user_pubkey = user_info @ { name } (user = $, pubkey = .pubkey);
    require(op_context.is_signer(user_pubkey.pubkey), "User must sign operation");
    return user_pubkey.user;
}
```

Add the operation below to `src/main/operations.rell`. It creates a new user:

src/main/operations.rell

```
operation create_user_info(name: text, pubkey: byte_array, street_address: text, zip_code: integer) {
    create user_info( name, pubkey, street_address, zip_code );
}
```

To change user information, add the `update_address` operation, which depends on verifying the user's public key, to `src/main/operations.rell`:

shell

```
operation update_address(name, new_street_address: text, new_zip_code: integer) {
    val verified_user = find_and_check_signer(name);
    update user_info @ { $ == verified_user } (
       .street_address = new_street_address,
       .zip_code = new_zip_code
    );
}
```

To list all existing users, add this query to `src/main/queries.rell`:

src/main/queries.rell

```nolines
query get_users_info() = user_info @* { } ( $.to_struct() );
```

Start the node so you can work with the database:

shell

```nolines
chr node start
```

Create a new key pair with this command:

shell

```nolines
chr keygen --file .secret
```

Call the `create_user_info` operation to add users:

shell

```nolines
chr tx create_user_info Artem 028A589B9EAA836ECFC52C59039A04231DBA4925873803BCD9B5E7151CF8611D89 "Drottninggatan 2" "100000"
```

shell

```nolines
chr tx create_user_info Erik 0835A7B8C9D0E1F2A3B4C5D6E7F8A9B0C1D2E3F4A5B6C7D8E9F0A1B2C3D4E5F6A7"Stureplan 52" "100001"
```

Change the user's address with the `update_address` operation:

shell

```nolines
chr tx update_address Erik "Stureplan 60" "200002" --secret .secret
```

Query all existing users:

shell

```nolines
chr query get_users_info
```

You should see output like this:

result

```
[
  [
    "name": "Artem",
    "pubkey": x"028A589B9EAA836ECFC52C59039A04231DBA4925873803BCD9B5E7151CF8611D89",
    "street_address": "Drottninggatan 2",
    "zip_code": 100000
  ],
  [
    "name": "Erik",
    "pubkey": x"0835A7B8C9D0E1F2A3B4C5D6E7F8A9B0C1D2E3F4A5B6C7D8E9F0A1B2C3D4E5F6A7",
    "street_address": "Stureplan 60",
    "zip_code": 200002
  ]
]
```

Written for this site from Chromia’s public course. Code samples are the course’s own.

[← Previous**Subqueries**](https://chromia.com/learn/rell-masterclass/sub-queries/)[Course done →**Start building**](https://chromia.com/developers/#start)

On this page

* [Example](#example)
