Tim Peters guides us in this area by recommending: "Flat is better than nested".
https://www.python.org/dev/peps/pep-0020/
But that isn't always possible, I know, so to answer your question instead of providing gratuitous quotations ...
As much as possible, I try to conceptualise "app-db" to be a database. That's the reason for that "db" in the name.
And, if you wanted to "update" a database, you need:
- the unique key of the thing to be updated
- the name of the table (collection).
Generally "path middleware" nicely handles the "name of the table" part of this pair. It gets your handler to the "root" of the data structure (table? collection?).
In the situation you are describing, the "unique key" bit is some sort of "path" into a data structure. There are layers of vectors and maps to traverse, even if middleware gets you to the base of this data structure you want to update.
In such a case, you'll have to "build the unique key" as you descend. A read-only cursor-like process.
So, let's imagine you represent your path as a vector (of keys or indexes), then in each level you would pass down this path vector, conj-ed with a new part of the id, incrementally building the unique key as you descend, and passing it down.
Then, at the leaves, when you "dispatch", you can include the path vector in the event payload. The handler then has the information it needs to perform the update.
This deep-tree situation is not a common usecase for me, but if you ran into this situation a lot, then I'd think about adapting the reagent cursors for the job.
In summary: when you dispatch, pass through the "unique key" (path), of the thing you want updated. Your handler may additionally have "path middleware" on it, which resolves the “name of the table” part of any update. So you get the job done via that combination.
A super simple version of this, can be seen here:
https://github.com/Day8/re-frame/blob/46b8848f3bab432832a4517f0cccf36cb4197f65/examples/todomvc/src/todomvc/handlers.cljs#L54-L58
"todo-ware" contains path middleware which gets the handler directly to the "todos table" (see the parameter "todos"), and the "id" in the event is the unique key required for the update. In your case, you'd just have a more complicated "id" (it's a vector created in a read-only cursor-like fashion).
I worry that I've simply told you what you already know here.
--
Mike