Fork me on GitHub

Has anyone ever played with reverse indexes in the fulcro db? Meaning, given some entity E, quickly find all other entities that reference E (via ident).

Björn Ebbinghaus15:02:45

You can have links between entities.

{:person/id {1 {:person/id 1, :person/cars [[:car/id 1] [:car/id 2]]}
 :car/id {1 {:car/id 1, :car/owned-by [:person/id 1]
          2 {:car/id 2, :car/owned-by [:person/id 1]}
Your graph query has to be a tree, your database does not. Fulcro has some functions that make working with this easy:
(require '[com.fulcrologic.fulcro.algorithms.normalized-state :as norm-state])

  {:person/id {1 {:person/id 1, :person/cars [[:car/id 1] [:car/id 2]]}}
   :car/id {1 {:car/id 1, :car/owned-by [:person/id 1]}
            2 {:car/id 2, :car/owned-by [:person/id 1]}}}
  [:car/id 1])
; => {:person/id {1 #:person{:id 1, :cars [[:car/id 2]]}}, 
;     :car/id {2 #:car{:id 2, :owned-by [:person/id 1]}}}

; Or remove a person.
  {:person/id {1 {:person/id 1, :person/cars [[:car/id 1] [:car/id 2]]}}
   :car/id {1 {:car/id 1, :car/owned-by [:person/id 1]}
            2 {:car/id 2, :car/owned-by [:person/id 1]}}}
  [:person/id 1])
; => #:car{:id {1 #:car{:id 1}, 
;               2 #:car{:id 2}}}

; remove-entity has a `cascade` parameter. A set of keywords, that should be followed and also removed.
  {:person/id {1 {:person/id 1, :person/cars [[:car/id 1] [:car/id 2]]}}
   :car/id {1 {:car/id 1, :car/owned-by [:person/id 1]}
            2 {:car/id 2, :car/owned-by [:person/id 1]}}}
  [:person/id 1]

; => {}


Thanks, I hadn't seen remove-entity. So I suppose it has to resort to a full db scan to find the entity to remove?


My use case is such that I'll need to find all references quite often…I'd have to measure if a full db scan is fast enough in all cases.


you could maintain a separate index of back references if you don't want to pollute your Fulcro db with them

Björn Ebbinghaus19:02:30

It is somewhat dependent on your use case. Are the back ref entities at predictable locations? Can you provide an example on how your data looks?


It's a normalized view of a language AST. And the language has references (symbols). I'd like to be able to answer questions like “which entities are referencing this one?”, so that I can implement things like refactoring (eg renaming a symbol needs to be able to find the files that should be modified)


A secondary index would probably work well.


Or just right in the referenced entity map, on a key like :symbol/users

Jakub Holý (HolyJak)17:02:50

Hi folks! I would appreciate you to the minimalist Fulcro tutorial. The key part is clarifying it is not truly minimalist since it focuses on full-stack applications and changing the description to clarify what the reader will learn (basic building blocks to be able to build Fulcro apps) and that there is also a number of extra things they might want to learn later to address other needs. What do you think? @mroerni ? If you have studied the minimalist tutorial - does the new description fit your experience? Does it set correct expectations? 🙏

Jakub Holý (HolyJak)22:02:35

Instead of packing for family holidays as I should, I spent the evening rewriting the Minimalist Fulcro Tutorial into smaller, independent parts so that it is more welcoming and even less scary to newcomers and so that people can pick only the parts relevant to what they are currently trying to do. I am not sure you how feasible the project is and how (and when!) it will turn out but I have the first part, which presents the contents of the series and has mostly new "Why Fulcro" (including a section on Fulcro vs re-frame I stole from Tony). Feedback please!

Björn Ebbinghaus12:02:19

Please. Enjoy your holiday. 🙂

❤️ 1

> The very core of Fulcro are not some features but its practical philosophy. Love that this part is mentioned early. > The UI is a a tree 💅 > Graph API This is a great section and is kinda central to explaining Fulcro. Maybe so much so that a simple would be helpful? Maybe just a simple tree representing the UI, with some labels showing which components "own" (query) particular subtrees? This isn't to say the section is worded unclearly or anything like that, just that it's such an important concept that perhaps making it less abstract with a visual to accompany would help drive the point home. Perhaps even two diagrams, comparing Fulcro's graph approach to the REST approach? > And such a normalized database also makes it trivial to find just the piece of data you want to change (all you need is the entity’s name, its ID value, and the property name). Might be a good place to mention the ident concept by name and maybe even show one. For myself, a big a-ha moment was when I understood (probably after reading it a few times 🙂 ), that an ident is basically just the first two of three parts of a get-in path through the client DB to get an entity's property. Overall, great intro here. I think it's much of Fulcro's approach is abstract and providing more concrete and self-contained examples would always help. Fulcro's unifying approach to everything might be a double-edged sword. On the one hand, once you "get it", everything further is a simple extension of the philosophy. On the other hand, I think that the unifying approach makes providing small, self-contained examples more difficult. Not a comment specific to your tutorial, but one point of friction in the Fulcro Book for me is that the term "database" is kind of overloaded to mean both server-side DB and the client DB, and the distinction is not always immediately obvious. Anyhow. Great stuff as always, @U0522TWDA. Please take my words only as feedback - I don't want to come off as unnecessarily critical because I really do appreciate the work you put in. Please do take some time off 🙂

❤️ 1
Jakub Holý (HolyJak)15:02:14

Thank you! The diagrams will come later, when I actually explain the stuff. IMO it's OK if it's somewhat unclear, I don't want to make it any long. Thx for sharing your experience with idents. Saying just what you did when I introduce idents coukd help others.


loved this sentense: > Reportedly, a perfectly designed REST APIs do not suffer from this problem. But they are rarer than unicorns.

❤️ 1
Quentin Le Guennec22:02:36

can I do this? (comp/transact! this [(mutation-a) (mutation-b)])


it means you want the two to be “grouped together” into the smallest execution. You’ll get the optimistic sides together, and the two will be sent to the server together IF they go to the same server

Quentin Le Guennec10:02:34

so there won't be any app state between mutation a and b right?


what do you mean? The book explains the semantics in great detail. a action will run, then b action. b will see the effects of a. Then any remote activity will be queued to whichever remote(s) a and b want (if any). If those go to the same server, it will make a single net request. When done, the ok or error actions of the mutations will be called, in order.