ash-project / ash

A declarative, extensible framework for building Elixir applications.
https://www.ash-hq.org
MIT License
1.6k stars 214 forks source link

Function atomic_ref/1 not found when doing a create with upsert?: true #1401

Closed adonig closed 1 month ago

adonig commented 1 month ago

Describe the bug My create action raises this error during while doing an upsert:

    ** (KeyError) key :atomic_validations not found in: {:not_atomic,
 "Failed to validate expression if hash != atomic_ref(hash) do\n  now()\nelse\n  updated_at\nend: %Ash.Error.Query.NoSuchFunction{function: :atomic_ref, arity: nil, resource: Apix.Catalog.Product, splode: nil, bread_crumbs: [], vars: [], path: [], stacktrace: #Splode.Stacktrace<>, class: :invalid}"}

To Reproduce Tried to do this in a create action that supports upsert:

      change atomic_update(
               :changed_at,
               expr(
                 if hash != atomic_ref(hash) do
                   now()
                 else
                   changed_at
                 end
               )
             )

Expected behavior It shouldn't raise an exception. Instead it should set changed_at to now() iff the hash changed.

Runtime

Additional context See #debugging Discord channel.

zachdaniel commented 1 month ago

@adonig I didn't spot this when I asked you to open a bug, but the problem is just one of syntax.

atomic_ref is a template like actor or arg

      change atomic_update(
               :changed_at,
               expr(
                 if hash != ^atomic_ref(:hash) do
                   now()
                 else
                   changed_at
                 end
               )
             )
adonig commented 1 month ago

Thank you! I believe we have to update the docs accordingly:

changes do
  change atomic_update(:slug, expr(fragment("slugify(?)", atomic_ref(:name)))), where: changing(:name), on: [:update]
end

I will create a PR for it.