Datascript 101 - Chapter 206 May 2016 clojurescript clojure
This is part 2 of 3 part series on Datascript. I suggest that you skim over Part 1 before reading this.
Random quote from Dune:
“It is so shocking to find out how many people do not believe that they can learn, and how many more believe learning to be difficult.” ― Frank Herbert, Dune
We will try to setup some identities and make our lives easier a bit.
Lets do this!
:car/model definition. You’re saying:
“Hey this :car/model field is going to be unique and will be used to identify this entity (a car in this case).”
These entity “identifiers” can be your domain specific things (so you don’t have to always rely on Datascript’s ID stuff), things like order numbers, email addresses etc.
Lets define an “identifier” (or an identity) for our makers as well.
We’ll be identifying our makers by their email addresses.
Level 3 - Insertion
Lets insert a new maker and a car along with it.
Some things to notice:
- We’re inserting a maker and a car together (like we did in our last chapter).
- We’re not using
-1to explicitly assign a temporary ID to our maker to be able to refer to it when adding our car (like we did in our last chapter).
- We’re using something called a “plz lookup a ref for me” (also know as “lookup-refs”) to identify our maker and then refer to it, that
[:maker/email "email@example.com"]is a lookup ref. So we don’t have to deal with
-1etc. or Datascript generated entity IDS.
Note that Datascript will still generate a
:db/id for us behind the scenes, but for all intents and purposes for now, you can use lookup-refs instead of entities wherever they’re needed.
All of this is fine and dandy, but what can I do with it other than easy insertions?
Level 2 - Querying
Concise entity lookups
In our last chapter, we had to write a pretty elaborate query to get the entity ID which we could pass to
d/entity. Now we can use a lookup-ref to fetch the same thing.
d/entity returns a “lazy” entity. When you fetch a certain attribute out of it, it will be resolved for you.
Level 4 - Insertion
We want to insert a new car now, and need the ref of our maker to insert it. Because of lookup refs we don’t have explictely query entity IDs:
WIN! We just used a lookup-ref to specify the maker!
Level 3 - Querying
Can we use these lookup-refs when querying stuff? Lets find all cars made by BWM.
Yay! See that
[?name ...] unholy-ness right after
:find? I will tackle that in my next chapter!
Level 5 - Insertion
ACHIVEMENT UNLOCKED! You’re still here!
What if BMW CEO decides that the name “BWM” needs to be changed to “BWM Motors”. How can we go and update the name? Lookup-refs make your life easier here as well:
You’re basically re-inserting a maker with a new name but the email is the same as the one we already have, it will be taken care of for you.
Here are some things to take away from this chapter:
- Lookup-refs are interchangeable with entity IDs almost everywhere, Datascript will complain when they’re not, so go ahead and use them liberally.
- Use identity and uniqueness to model your domain specific “identifiers”.
Things to try
- Insert some more makers and cars.
- Try adding some more attributes and identities to the schema and try and use them.
All of the stuff here is available as a gist here.
I will see you next time!