ganymede
How do you handle multiple changes without using multiple database requests?
How do y’all handle multiple changes without using multiple database requests. This is something I came up with but I am wondering if there’s already a solution I just haven’t found.
I made a fancy diagram but I am not allowed to post it.
The Draft module implements an optimistic UI pattern where changes are buffered in memory and persisted as a single, atomic unit.
| Component | Description |
|---|---|
%Draft{} |
The Draft stores the original data in source and keeps track of mutations in the changes field. |
Draft.Diff |
Compares the difference between the original source (initial state) and changes (current state). |
Draft.Validations |
Use Ecto Changesets to validate data before they are applied to the changes map. Batched operations are checked as a group, if any fail, the entire batch is rejected with errors collected for the UI. |
Draft.Commit |
Atomic persistence, translates the list of ordered mutations into an Ecto.Multi. Handles tmp_id resolution for newly inserted entities. |
Most Liked Responses
felix-starman
I apologize if this seems rude, I’m just trying to gauge what it is that you’re trying to solve or get advice on , but the shape of what you describe seems basically the same as a changeset in ecto, or any of the other parsing or validation or schema libraries such as Drops, or Zoi, or …
If it’s something that needs to be persisted before it’s committed to the main entity, then I have a concept of it in the database and it’s just a matter of whether I store a map of some embedded schema, or something more formal.
If it does not need to be persisted or a process dying like a liveview refreshed for example, then I just store it in the socket or whatever mechanism of process state I’m using and updated or recompute it with every new set of changes until it’s ready to be applied. I tend to only use an extra changeset for very simple one or two step flows, as it’s way too easy to reuse a changeset twice which is a No-No. Usually if it’s just a little bit bigger than that and I want to protect myself from messing up. I will receive the form, turn it into a changeset if it’s valid, and if they don’t want to apply it yet, then I will just capture the params they sent or the cast attributes and then just append when they want to add another thing. So I basically I don’t keep the changeset. I just use it to make a decision and then I throw it away or keep it only for calling to_form.
Once I get into UI “wizard” territory or some sort of state machine, I make a custom reducer module and then decide how to save and restore the state if I need to.








