Using optimistic locking and AshCloak?

I have a resource where I’m using AshCloak on an attribute. I’d also like to use optimistic locking to prevent conflicting changes.

  actions do
    defaults [:read, :create, :destroy]
    default_accept [:name, :phone_number]

    update :update 
  end

  changes do
    change optimistic_lock(:version), on: [:create, :update, :destroy]
  end

  cloak do
    vault(MyApp.Vault)

    attributes([:phone_number])
    decrypt_by_default([:phone_number])
  end

However, when I try and update the record I’m seeing the following error.

[warning] Unhandled error in form submission for MyApp.Customer.update

This error was unhandled because Ash.Error.Framework.MustBeAtomic does not implement the `AshPhoenix.FormData.Error` protocol.

** (Ash.Error.Framework.MustBeAtomic) MyApp.Customer.update must be performed atomically, but it could not be

Reason: AshCloak.Changes.Encrypt does not implement `atomic/3`

See https://hexdocs.pm/ash/3.0.0/update-actions.html#atomic-updates for more on atomics.

In an attempt to resolve this, I tried adding def atomic to lib/ash_cloak/changes/encrypt.ex (as below), and this resolved the error, but broke writes to the encrypted_phone_number field.

  @impl true
  def atomic(changeset, opts, context) do
    {:ok, change(changeset, opts, context)}
  end

I also tried returning a plain :ok with no change.

I’ve added an atomic implementation in v0.1.2 of ash_cloak. Try it out and LMK :slight_smile:

OMG. That was an insane turn around time.

That just worked.

Thank you so much Zach!

1 Like