Rollback record with Carbonite

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!()
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!()
** (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!()
2 Replies
ZachDaniel
ZachDaniel3y ago
Hmm…well, you don’t generally want to use Changeset.new The documentation for that function explains it 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#2001
tommasop#2001OP3y ago
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
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
customer_revert =
customer_update_two
|> Changeset.for_update(:force_update, data_changes)
|> MmsBiztalk.update!()
|> MmsBiztalk.load!([:data_in])

assert customer_revert == customer

Did you find this page helpful?