Rollback record with Carbonite
tommasop:
I’m trying to achieve the title result.
The problem is that trying to set some fields (like foreign keys and timestamps) back to their previous values will mark the changeset as invalid.
I’m using
force_change_attributes
to try to overcome the problem but it is not woking.
Is there a way to force the changeset to accept all attributes changes without validating them?
Or is there a better way to achieve what I’m trying to achieve?
customer_revert =
Changeset.new(customer_update_two)
|> Changeset.force_change_attributes(data_changes)
|> MmsBiztalk.update!()
** (Ash.Error.Invalid) Input Invalid
* Invalid value provided for updated_at: cannot be changed.
~U[2023-04-12 07:43:32.314706Z]
(ash 2.6.29) lib/ash/changeset/changeset.ex:1037: anonymous fn/2 in Ash.Changeset.validate_attributes_accepted/2
.....
* Invalid value provided for data_in_id: cannot be changed.
"8b4951f6-055c-4d9d-a498-8e2eeeb06e74"
(ash 2.6.29) lib/ash/changeset/changeset.ex:1037: anonymous fn/2 in Ash.Changeset.validate_attributes_accepted/2
....
code: |> MmsBiztalk.update!()
ZachDaniel:
Hmm…well, you don’t generally want to use
Changeset.new
ZachDaniel:
The documentation for that function explains it
ZachDaniel:
And then I’d probably suggest:
Write an action that accepts all attributes and has arguments for all private/immutable attributes and uses something like
change set_attribute(:updated_at, arg(:updated_at))
to force change them.
tommasop:
So here is the solution:
update :force_update do
argument :data_in_id, :uuid
argument :updated_at, :utc_datetime_usec
change set_attribute(:data_in_id, arg(:data_in_id))
change set_attribute(:updated_at, arg(:updated_at))
end
customer_revert =
customer_update_two
|> Changeset.for_update(:force_update, data_changes)
|> MmsBiztalk.update!()
|> MmsBiztalk.load!([:data_in])
assert customer_revert == customer