automatic / computed references between dependent entities #1972
-
Is there a way to keep references up to date between two entities. Here, I have a simple model with const Row = t.model("row", {
id: t.refinement(t.identifier, id => isUUID(id)),
order: t.string,
table: t.reference(t.late((): IAnyModelType => Table)),
})
const Table = t
.model("table", {
id: t.refinement(t.identifier, id => isUUID(id)),
rows: t.map(t.reference(t.late((): IAnyModelType => Row))),
})
.actions(self => ({
addRow: (row) => void (self.rows.set(row.id, Row.create(row))),
}))
const State = t.model("state", {
tables: t.map(Tables),
rows: t.map(Row),
}) My newbie intuition is to use listeners such as A simpler problem with one entity is automatic managing parent-children dependencies. If a child node is added or deleted, is there a way to update the children map of its parent? Is there a way to delete all children recursively if a parent is deleted? const Node = t.model("node", {
id: t.refinement(t.identifier, id => isUUID(id)),
children: t.map(t.reference(t.late((): IAnyModelType => Node))),
parent: t.reference(t.late((): IAnyModelType => Node))
}) (Sorry if the question is too basic; new to mobx and mst, and don't know how to model and update entities compared to Postgres 😅 ). |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 6 replies
-
I have found a naive solution using // Equivalent of a cascading deletion when foreign key is deleted.
export const deleteSelf = ({ cause, parent }) => void (cause == "destroy" && remove(getParent(parent), parent.id));
const Row = t
.model("row", {
id: t.refinement(t.identifier, id => isUUID(id)),
order: t.string,
table: t.reference(t.late((): IAnyModelType => Table), { onInvalidated: deleteSelf }),
});
const Table = t
.model("table", {
id: t.refinement(t.identifier, id => isUUID(id)),
})
.views(self => ({
get rows() {
return values(getRoot(self).rows).filter(row => row.table.id == self.id);
}
}))
.actions(self => ({
addRow: (row) => {
const root = getRoot(self);
unprotect(root); // mst doesn't like when subtrees modify their parents
set(root.rows, row.id, {...row, table: self.id});
protect(root);
}
}))
const State = t
.model("state", {
tables: t.map(Tables),
rows: t.map(Row),
}) |
Beta Was this translation helpful? Give feedback.
-
This is a clear indication that your action needs to live higher in the tree.
Also, any specific reason to keep your references in a map? A simple list would work better since the snapshot would be just a list of strings. |
Beta Was this translation helpful? Give feedback.
-
Marking @antondomratchev's answer as correct here based on the discussion. Thanks, y'all! |
Beta Was this translation helpful? Give feedback.
My apologies I was looking at the first example of the code you provided. Where Table model was defining rows as a property.
You can use something like
getRoot(self).addRow(self.id, row)
this code assumes that current model is attached to the root node and the root node has aaddRow
action. I tend to sprinkle aroot
view across my child models because i often dive to the root of the tree and traverse…