# One-to-one relationship · Relationships in Rell explained · Learn Chromia

> In a one-to-one relationship, each record in one table matches exactly one record in another table. Consider a library system: every library has its own…

Source: https://chromia.com/learn/relationships-course/one-to-one/

Relationships in Rell explainedLesson 5 of 6

1. [01Relationships in Rell explained](https://chromia.com/learn/relationships-course/introduction/)
2. [02Creating Records](https://chromia.com/learn/relationships-course/joins/)
3. [03Many-to-many relationships](https://chromia.com/learn/relationships-course/many-to-many/)
4. [04One-to-many relationships](https://chromia.com/learn/relationships-course/one-to-many/)
5. [05One-to-one relationship](https://chromia.com/learn/relationships-course/one-to-one/)
6. [06Set up your project](https://chromia.com/learn/relationships-course/setup/)

[Learn](https://chromia.com/learn/)[Relationships in Rell explained](https://chromia.com/learn/relationships-course/)

05 / 06

# One-to-one relationship

In a one-to-one relationship, each record in one table matches exactly one record in another table. Consider a library system: every library has its own unique address, and every address belongs to exactly one library. Each library entry therefore maps to a single, specific address.

A traditional relational database models this with separate tables linked by foreign keys. Guaranteeing uniqueness and data integrity this way adds complexity. The following SQL shows a typical one-to-one setup:

sql

```
CREATE TABLE Address (
    id INT PRIMARY KEY,
    street VARCHAR(255),
    city VARCHAR(255),
    postalCode VARCHAR(10)
);

CREATE TABLE Library (
    id INT PRIMARY KEY,
    name VARCHAR(255),
    address_id INT,
    FOREIGN KEY (address_id) REFERENCES Address(id)
);
```

The schema works as follows:

* **Address table**: Stores the address details and uses a primary key ID to uniquely identify each address.
* **Library table**: Stores the library details plus a foreign key, `address_id`, that points to the ID in the `Address`
  table. The `UNIQUE` constraint prevents an address from being linked to more than one library.

Rell removes the need to manage foreign keys and constraints by hand: you reference entities directly.

Start by creating a `library_management` directory inside `/src`. In it, add a `module.rell` file containing this code:

src/library\_management/module.rell

```nolines
module;
```

Next, add an `entities.rell` file to the `/src/library_management` directory with the following code:



src/library\_management/entities.rell

```
entity library {
    library_name: text;     // Name of the library
    key address;    // One-to-one relationship with Address
}

entity address {
    street: text;         // Street address
    city: text;           // City name
    postal_code: text;    // Postal code
}
```

sql

```
create table "c0.address"(
  "rowid" bigint not null,
  "street" text not null,
  "city" text not null,
  "postal_code" text not null,
  constraint "PK_c0.address"
    primary key ("rowid")
);

create table "c0.library"(
  "rowid" bigint not null,
  "name" text not null,
  "address" bigint not null,
  constraint "PK_c0.library"
    primary key ("rowid"),
  constraint "c0.library_address_FK"
    foreign key ("address")
    references "c0.address" ("rowid"),
  constraint "K_c0.library_0"
    unique ("address")
);
```

Now write an operation that adds a library together with its address. It creates both a `Library` and an `Address` record and connects them.

Add an `operations.rell` file to the `/src/library_management` directory with this code:

/src/library\_management/operations.rell

```
operation create_library(name: text, street: text, city: text, postal_code: text) {
    val library_address = create address(street, city, postal_code);
    create library(name, library_address);
}
```

The operation first builds an address instance from the supplied street, city, and postal code. It then creates a library from the supplied name and that address instance. Rell links the two records for you.

To make testing easier, define queries that return the stored records. Put this code in the `queries.rell`
file:

src/library\_management/queries.rell

```
query get_all_library() = library @* {} ( id = .rowid, .library_name, city = .address.city, street = .address.street, postal_code = .address.postal_code );

query get_library_by_name(library_name: text) = library @ { library_name };
```

## Testing

Add tests to confirm that the code behaves as expected. Rell supports writing tests in test modules.

Open `src/test/my_library_test.rell` and add a test. It creates a library with an address, then calls a query that returns every library in the database and checks how many there are:

src/test/my\_library\_test.rell

```
@test module;

import library_management.{ create_library, get_all_library };

function test_create_library() {
    // Create a new library with an address
    rell.test.tx()
        .op(create_library("Biblioteca Apostolica Vaticana", "Città del Vaticano", "Vatican", "00120"))
        .op(create_library("New York Public Library", "476 5th Ave", "New York", "10018"))
        .run();

    val all_libraries = get_all_library();
    assert_equals(all_libraries.size(), 2);
}
```

From the project folder, run this command in the terminal to execute the test:

shell

```nolines
chr test
```

A passing test produces output like this:

shell

```
====================Running unit tests====================
TEST: test.my_library_test:test_create_library
OK: test.my_library_test:test_create_library (5.010s)

------------------------------------------------------------
TEST RESULTS:

OK test.my_library_test:test_create_library

SUMMARY: 0 FAILED / 1 PASSED / 1 TOTAL (5.010s)

***** OK *****
```

## Creating new records

The example below uses the Chromia CLI to add library records. The next section queries those same records.

You need a local Chromia node running to work with the database. While experimenting, start the node with the `--wipe` flag, which deletes all records currently stored.

shell

```nolines
chr node start --wipe
```

A one-to-one relationship requires records in two tables, `library` and `address`. The `create_library` operation defined earlier creates both.

The commands below call `create_library` twice, passing the required arguments each time, to create two pairs of related records:

shell

```nolines
chr tx --await create_library "Biblioteca Apostolica Vaticana" "Città del Vaticano" "Vatican" '"001201"'
```

shell

```nolines
chr tx --await create_library "New York Public Library" "476 5th Ave" "New York" '"10018"'
```

Each successful call should return:

shell

```nolines
transaction with rid 0CAADC0937030F67C78003E2F9C1CA15E8C5D0C280ACA295CB8CD747AA09FBD9 was posted CONFIRMED
```

## Querying new records

To fetch the new records, run `get_all_library` from the Chromia CLI:



shell

```nolines
chr query get_all_library
```

The query returns:

json

```
[
  [
    "city": "Vatican",
    "id": 2,
    "library_name": "Biblioteca Apostolica Vaticana",
    "postal_code": "001201",
    "street": "Citta del Vaticano"
  ],
  [
    "city": "New York",
    "id": 4,
    "library_name": "New York Public Library",
    "postal_code": "10018",
    "street": "476 5th Ave"
  ]
]
```

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

[← Previous**One-to-many relationships**](https://chromia.com/learn/relationships-course/one-to-many/)[Next →**Set up your project**](https://chromia.com/learn/relationships-course/setup/)
