patrickdm
How to use Ecto optimistic_lock with Phoenix generated update action?
Hello,
I’ve been trying to implement Ecto.Changeset.optimistic_lock in a Phoenix application but I’m stuck with the generated controller’s update action.
In iex I have success rising an Ecto.StaleEntryError when I try to update a stale record, (as shown in the documentation):
iex> post = Repo.insert!(%Post{title: "foo"})
%Post{id: 1, title: "foo", lock_version: 1}
iex> valid_change = Post.changeset(:update, post, %{title: "bar"})
iex> stale_change = Post.changeset(:update, post, %{title: "baz"})
iex> Repo.update!(valid_change)
%Post{id: 1, title: "bar", lock_version: 2}
iex> Repo.update!(stale_change)
** (Ecto.StaleEntryError) attempted to update a stale entry
here the two changeset are being generated from the same post struct, and Repo.update raise the expected error.
On the other hand, when the update is performed concurrently in two browser windows, -my understanding is that- the controller’s update action performs a new get_post!(id) and then uses that struct to make the update’s changeset, with the form params; therefore the latest update is always overwriting the first occurring, thus making optimistic_lock useless in this context.
I couldn’t find much help on this issue, and it make me think I’m getting all this wrong.. Thank’s for any help.
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #elixirconf-us
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #performance
- #security










First 4 of 4 Posts
1player
That’s an interesting question. Disclaimer: I’ve never used
optimistic_lock.Since
lock_versionis just a regular field, one idea would be to pass, alongside with the ID, the version of the object in the update method and using that version before you apply any changes.Example, in your form:
And in your controller:
Now you will will get a StaleEntryError if you’re updating an old post.
EDIT: you might want to use
hidden_inputto generate the hidden field instead of doing it manuallypatrickdm
Hello
1playerand thank you,Oh
, right, that easy 
Replacing the validly-updated new :lock_version with the stale one after
get_post!(id)… I’m going to try this now, sure it is going to work!I’ve been stubbornly poking around with attempts to pass the post struct assigned in edit, from the form to the update action, with no success, and I couldn’t think simple again. Thank you for your help!
Kurisu
Hello @patrickdm! I was wondering if you could share your approach to managing the
Ecto.StaleEntryErrorexception within a controller or a live view?I came across a similar issue discussed in another thread during my research, but unfortunately, it didn’t have any responses. Your insights would be greatly appreciated.
Kurisu
After conducting further research, I believe I’ve found a suitable solution to my question, particularly in relation to LiveView.
Here’s the section I found in the docs: Error and exception handling — Phoenix LiveView v1.2.5