# 04: refs

In all the examples so far, all the todo lists have referred to the same user, `:u0`. What if you want to create two todo lists, but you want them to belong to different users? Here's how you could do that:

```scheme
(ns reifyhealth.specmonstah-tutorial.04
  (:require [reifyhealth.specmonstah.core :as sm]))

(def schema
  {:user  {:prefix :u}
   :topic {:prefix    :t
           :relations {:owner-id [:user :id]}}
   :post  {:prefix    :p
           :relations {:topic-id [:topic :id]
                       :owner-id [:user :id]}}})
(defn ex-01
  []
  (sm/add-ents {:schema schema} {:topic [[2 {:refs {:owner-id :my-own-sweet-user}}]
                                         [1]]}))
                                         
(sm/view (ex-01))
```

![](https://4068685904-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LoN3fu4ydp8osDZFQch%2F-LowSPG3h_NH7XsMAjZV%2F-LowSaLx5otrThpipwrG%2Fcustom-ref.png?alt=media\&token=db0c5054-3751-4c3b-bad7-65a7a7babc65)

What's new in this example is the map `{:refs {:owner-id :my-own-sweet-user}}`. It resulted in two todo lists, `:tl0` and `:tl1`, referring to a `:user` ent named `:my-own-sweet-user` instead of `:u0`. `:t2` refers to `:u0`, as we've seen before. Let's break this down.

In the `schema`, `:topic` includes this relations definition:

```scheme
:relations {:owner-id [:user :id]}
```

This means, *`:topic`s refer to a user via the `:owner-id` attribute*. Remember that queries are essentially telling Specmonstah, *generate the minimal ent-db necessary for me to retrieve the ents I've specified*, so when you call the `add-ents` function and instruct SM to generate a `:topic`, SM's default behavior is to satisfy this schema definition by creating a `:user` and naming it according to its default naming system.

Internally, the ent db tracks that the `:topic` refers to the `:user` via the `:owner-id` attribute, and when your query includes the option `{:refs {:owner-id :my-own-sweet-user}}`, you're saying, *I want the user that `:owner-id` refers to to be named `:my-own-sweet-user`*. One reason you might do this would be to write a test ensuring that users can't modify each others' topics.

If you look back at the schema for this section, you'll notice it introduced a new ent type, `:topic`, and `:post`s reference `:topic`s. What if you wanted to create two topics, each with one post and each topic belonging to a different user? Here's how you could do that:

```scheme
(defn ex-02
  []
  (sm/add-ents {:schema schema} {:topic [[1]
                                         [1 {:refs {:owner-id :hamburglar}}]]
                                 :post  [[1]
                                         [1 {:refs {:topic-id :t1}}]]}))
                                         
(sm/view (ex-02))
```

![](https://4068685904-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LoN3fu4ydp8osDZFQch%2F-LowSPG3h_NH7XsMAjZV%2F-LowTcHI6JIRUtA-BOHA%2Fhamburglar.png?alt=media\&token=510f99c0-bd83-4260-8bae-7ea07ea2cf77)

Before reading the explanation of how this works, indulge the educator in me and take a moment to write or say your own explanation. Quizzing yourself like this is an effective way to clarify and retain your understanding. There's all kinds of studies that show it; it's called "the testing effect" and it's one of the best ways to learn.

Let's break this query down term by term:

```scheme
{:topic [[1]
         [1 {:refs {:owner-id :hamburglar}}]]
 :post  [[1]
         [1 {:refs {:topic-id :t1}}]]}
```

Under `:topic`, `[1]` tells Specmonstah to create a `:topic`. It's given the default name `:t0`. Since you didn't specify any refs, it refers to the default user, `:u0`.

The next query term, `[1 {:refs {:owner-id :hamburglar}}]`, instructs SM to create a `:topic` that refers to a user named, of all things, `:hamburglar`. This `:topic` is given the default name of `:t1`.

Under `:post`, `[1]` tells Specmonstah to create a `:post` with a default name and default refs. Therefore, `:p0` refers to `:t0`.

The next term, `[1 {:refs {:topic-id :t1}}]`, tells SM that the next `:todo` should refer to the `:topic` named `:t1`. We specified the `:t1` here because we know that Specmonstah's naming system will produce that name for the second `:topic` specified in the query.

The point of all this is that you can rely on Specmonstah's naming system to reliably and concisely establish the properties and relations of the ent db you want to generate. If you don't want to keep track of Specmonstah's implicit names, you can name things explicitly:

```scheme
(defn ex-03
  []
  (sm/add-ents {:schema schema} {:topic [[:t0]
                                         [:t1 {:refs {:owner-id :hamburglar}}]]
                                 :post  [[1 {:refs {:topic :tl0}}]
                                         [1 {:refs {:topic :tl1}}]]}))
```
