dewetblomerus
Do not touch `updated_at` when upsert has no effect
This is not important, I’m just curious about how it would be done.
The updated_at field on my User gets bumped on every login, even if no fields changed. Auth0 already saves all the history about successful and unsuccessful logins, so I only want updated_at to be bumped when one of the fields for the User resource is being changed to a different value.
I followed this guide and then made some changes and eded up with the following action:
create :register_with_auth0 do
argument :user_info, :map, allow_nil?: false
argument :oauth_tokens, :map, allow_nil?: false
upsert? true
upsert_identity :unique_auth0_id
# Required if you have token generation enabled.
change AshAuthentication.GenerateTokenChange
# Required if you have the `identity_resource` configuration enabled.
change AshAuthentication.Strategy.OAuth2.IdentityChange
change fn changeset, _ ->
user_info = Ash.Changeset.get_argument(changeset, :user_info)
changes = %{
"email" => Map.get(user_info, "email"),
"auth0_id" => Map.get(user_info, "sub")
}
Ash.Changeset.change_attributes(
changeset,
changes
)
end
end
Marked As Solved
zachdaniel
this may actually be something the framework should handle for you? Like if something has an update_default, it should only be applied if something is changing. We actually could solve for this in the update, i.e fields that are being set due to update_defaults would be set only if at least one other thing is changing…The difficulty is pairing that with atomics, i.e we don’t know if nothing is changing until we actually do the upsert. There are a few things we’d need to do to make this work, incrementally, that are on the roadmap that is in my brain
.
- add an expression variable that lets you refer to the thing you are replacing in an upsert.
- add an expression variable that corresponds to wether or not you are in an upsert.
- add an expression variable that corresponds to wether or not something is changing if you are in an upsert. # this one may or may not be reasonable
So then you could use an atomic_update to get this behavior in the short term, and then in the long term the framework can do this automatically. In a create, set the value, in an update, only set if something is changing.
change atomic_update(:updated_at, expr(
if ash.updating? and ash.has_changes? do
now()
else
updated_at
end
))
But yeah none of that will happen in the short term. Someday ![]()
Also Liked
jimsynz
zachdaniel
I don’t recall what I was getting at
But I think what I was implying was try to call the action in iex (with the upsert_fields: {:replace_all_except, ...} option passed that was giving you trouble) as opposed to submitting a form.
dewetblomerus
Thanks a million for all the effort you have put into something that was merely an annoyance for me. The least I can do is open an issue. I’ll also try to provide a more minimal example for reproducing it. I don’t think Ash Authentication or Phoenix would need to be involved.







