Fork me on GitHub
#datascript
<
2023-11-19
>
Sam Ferrell20:11:01

Is there any tactic to make changes to a component entity without needing its unique identifier? For example...

(def my-schema
  {:db/ident     {:db/unique :db.unique/identity}
   :user/window  {:db/valueType :db.type/ref}
   :user/windows {:db/valueType :db.type/ref :db/cardinality :db.cardinality/many :db/isComponent true}})

(def my-tx
  [[:db/add -1 :db/ident :local-user]
   [:db/add -1 :user/window -2]
   [:db/add -2 :window/zoom 1.15]])
A user has many windows, but only one active ( :user/window ). Obviously this transaction replaces the :user/window instead of updating the entity it already references. I need to add [:db/add -2 :some-unique-attr ?] to make it work. I figure if I know its a reference to a component entity then I might be able to update that entity without needing to query it for its unique identifier. Normally I would be able to give the window entity a :db/ident like :current-window but the state is replicated to many peers (`:local-user` is a special case that I manage for each peer). Theoretically I could make another special case exception but that sounds like a lot of work.

Sam Ferrell01:11:16

Thinking more about this, I think I can solve this by using :db/ident and filtering those attributes out from being replicated to peers

Niki15:11:52

probably a transaction function

Niki15:11:45

Something like

(defn update-user-window [db user window]
  (let [user   (d/entity db user)
        window (:user/window user)]
    [(merge
       {:db/id (:db/id window)}
       window)]))

(d/transact! conn
  [[:db.fn/call update-user-window [:db/ident :local-user] {:window/zoom 1.15}]])

👍 1