The recommendation for enums in Datomic is to use :db/ident. Using :db/ident
as an enum value complicates the use with d/pull
. Everywhere you pull an entity, you'll need to write code to deal with the nested enum entity. For example, say I have a :user/type
enum that is defined as suggested by that doc (card one, ref attr). Anytime I pull my :user/type
attribute, I need to write code to unnest the :user/type
value.
(d/pull (d/db conn) '[:user/type] [:user/id "a"])
=> #:user{:type #:db{:id 87960930222153, :ident :user.type/a}}
How are folks dealing with this? Just always wrapping the d/pull
return with something like (update :user/type :db/ident)
? Perhaps always remembering to specify the pull pattern for all enum attributes as (:user/type :xform my-ns/get-db-ident)
, where my-ns/get-db-ident
is just (def get-db-ident :db/ident)
?
I asked this question in the #datomic channel in Clojurians Slack and figured I'd move it here so it would persist. Other folks replied with some other ideas.
Tyler Nisonoff suggested a postwalk from every pull result. e.g.,
(clojure.walk/postwalk
#(match %
{:db/ident ident} ident
:else %)
nested-entity)