Ash FrameworkAF
Ash Frameworkโ€ข3w agoโ€ข
12 replies
Pit

Update during read if record found

I have a use-case where I want to find a record and, if a record is found, update the selected record before the action returns it. The use-case is effectively a job-queue in which I want to be able to claim a job, if one is available, within a single transaction, or just return nothing.

I attempted the following:

read :get_and_claim do
  get? true

  prepare fn query, _ -> Ash.Query.lock(query, :for_update)
  prepare build(limit: 1)

  # my filters to get a matching row

  prepare after_action(fn query, records, _context ->
    with [record] <- records do
        {
          :ok,
          [
            record
            |> Ash.Changeset.for_update(:claim)
            |> Ash.update!()
          ]
        }
    end
  end)
end


Unfortunately, the record returned when I invoke the action is still the record's state prior to the changes done by
after_action
. (I confirmed through a repeated read that the actual change was persisted.)

Maybe not returning the updated records is something that is expected of Ash.Subject.after_action (which AFAICT is what a prepare
after_action
resolves to), but what I expected is the behavior documented for Ash.Query.after_action that indicates that records can be enriched/changed.

Any ideas on how to solve this? I'm also happy to hear about alternative paths that are maybe more idiomatic than my attempt of updating during a read action. Thanks. ๐Ÿ™‚
Was this page helpful?