This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2015-11-28
Channels
- # admin-announcements (21)
- # beginners (102)
- # boot (8)
- # cider (40)
- # cljsrn (2)
- # clojure (52)
- # clojure-nl (2)
- # clojure-russia (6)
- # clojure-taiwan (2)
- # clojure-uk (1)
- # clojurescript (363)
- # datavis (22)
- # datomic (69)
- # emacs (4)
- # hoplon (1)
- # immutant (2)
- # jobs-rus (13)
- # ldnclj (6)
- # lein-figwheel (2)
- # leiningen (9)
- # liberator (1)
- # off-topic (1)
- # om (68)
- # onyx (28)
- # parinfer (3)
I am trying to model a shopping basket with some items in the basket and figured that the items should be a component of the basket
I noticed that when I add another element to the basket that the items are duplicated
@raymcdermott: so that's a bug right ?
or maybe to put another way… that I’m finding it unintuitive to model the current state of the items in the basket using the component model
@raymcdermott: I'm not sure I understand what you get
could you put some code somewhere maybe ?
(def cart [{:db/id #db/id [:db.part/user -1]
:cart/id #uuid "d213198b-36b5-4c19-8cb1-e172f59091d9"
:cart/name "My Shopping Cart"
:cart/sku-counts
[
{:sku-count/sku 12345
:sku-count/count 1}
{:sku-count/sku 54321
:sku-count/count 2}
]
}
])
(def new-cart [{
:db/id 17592186045421
:cart/sku-counts
[
{:sku-count/sku 12345
:sku-count/count 1}
{:sku-count/sku 54321
:sku-count/count 2}
]
}
])
is :sku-count/sku
an identity field ?
{:db/id #db/id[:db.part/db]
:db/ident :sku-count/sku
:db/valueType :db.type/long
:db/cardinality :db.cardinality/one
:db/doc "Number of the SKU"
:db.install/_attribute :db.part/db}
It's normal that it gets duplicated then. 2 strategies here :
{:db/id #db/id[:db.part/db]
:db/ident :cart/sku-counts
:db/isComponent true
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/many
:db/doc "SKUs with counts for this cart"
:db.install/_attribute :db.part/db}
1) have an identity field on the cart items, and do insert or update based on whether the line item is created or updated
2) On each transaction, erase the past line items and replace with the updated ones (it's a 'document-like' approach)
ok, so in either case I have to take care of the state rather than (my naive understanding) that it would be handled by Datomic because from my view there is no novelty
For the second approach, I ended up writing a database function that does this:
click the + sign in the bar at the bottom of the screen
And it's not that common - don't be too eager to use something like this
@raymcdermott: what do you mean?
Most of the time I would add /update /delete the line items individually, instead of 'resetting' the cart all the time
I didn't have a choice, I was migrating from a Document database, and my legacy clientside code relied on this design
@val_waeselynck: thanks for the suggestions
it really depends on what granularity is permitted on the client
One thing to consider is that transaction functions are more costly
in performance
the nested map is probably ideal for a case where the data will not change or only rarely
I guess another benefit is that deleting the outer item will delete the components so that’s less tedious
@raymcdermott: have fun!
(clojure.pprint/pprint (d/pull db '[*] cart-id))
{:db/id 17592186045421,
:cart/id #uuid "d213198b-36b5-4c19-8cb1-e172f59091d9",
:cart/name "My Shopping Cart",
:cart/sku-counts
[{:db/id 17592186045422, :sku-count/sku 12345, :sku-count/count 1}
{:db/id 17592186045423, :sku-count/sku 54321, :sku-count/count 2}
{:db/id 17592186045425, :sku-count/sku 12345, :sku-count/count 1}
{:db/id 17592186045426, :sku-count/sku 54321, :sku-count/count 2}]}
but I am struggling to locate the right way to achieve the retraction … docs are not feeling obvious
(def retraction [:db/retract 17592186045422 :sku-count/sku 12345 :sku-count/count 1])
=> #'shopping-cart-demo.datomic/retraction
@(d/transact conn retraction)
IllegalArgumentExceptionInfo :db.error/not-transaction-data Transaction data element must be a List or Map, got :db/retract datomic.error/arg (error.clj:57)
@raymcdermott: that's the one you want
@raymcdermott: try to always picture the low-level set of datoms that is involved
I think you're querying on an old version of your db