10: uniqueness constraint
If you're building a forum and want people to be able to like posts, you probably don't want to allow people to like the same post twice. If your schema is something like this:
like
post-id
user-id
Then you probably have a constraint such that you can't have two records with the same post-id and user-id. How do you model this in Specmonstah? So far, we've seen schemas like this:
1
(ns reifyhealth.specmonstah-tutorial.10
2
(:require [reifyhealth.specmonstah.core :as sm]))
3
4
(def bad-schema
5
{:user {:prefix :u}
6
:post {:prefix :p}
7
:like {:prefix :l
8
:spec ::like
9
:relations {:post-id [:post :id]
10
:created-by-id [:user :id]}}})
Copied!
If you use this to generate ents, you'll end up in a disappointing situation:
1
(defn ex-01
2
[]
3
(sm/view (sm/add-ents {:schema bad-schema} {:like [[3]]})))
4
(ex-01)
Copied!
likes all reference the same post and user
All the likes reference the same :post (:p0) and :user (:u0). This happens because Specmonstah generates the minimal data needed to satisfy a query.
To get Specmonstah to generate data that your database will accept, you introduce a uniqueness constraint in the schema:
1
(def good-schema
2
{:user {:prefix :u}
3
:post {:prefix :p}
4
:like {:prefix :l
5
:spec ::like
6
:relations {:post-id [:post :id]
7
:created-by-id [:user :id]}
8
:constraints {:created-by-id #{:uniq}}}})
Copied!
Notice the :constraints key at the bottom of the schema. This tells Specmonstah, "The :created-by-id relation of every :like should refer to a unique :user. If you generate multiple :likes, generate new :users too until each like refers to a differ :user."
This schema will generate a graph that will satisfy your database's constraints:
1
(defn ex-02
2
[]
3
(sm/view (sm/add-ents {:schema good-schema} {:like [[3]]})))
4
(ex-02)
Copied!
a happy graph
You could have instead added the :uniq constraint to :post-id, and it would have generated new :posts instead of :users. Give it a try :) Or, try adding the constraint to both :post-id and :created-by-id.
Last modified 2yr ago
Copy link