Incrementing an attribute

What I have been doing is this:
change fn changeset, opts ->
attempts = Ash.Changeset.get_attribute(changeset, :attempts)
Ash.Changeset.change_attribute(changeset, :attempts, attempts + 1)
end
change fn changeset, opts ->
attempts = Ash.Changeset.get_attribute(changeset, :attempts)
Ash.Changeset.change_attribute(changeset, :attempts, attempts + 1)
end
I did speculatively try this with expr as well: šŸ™‚
change set_attribute(:attempts, expr(attr(:attempts) + 1)
change set_attribute(:attempts, expr(attr(:attempts) + 1)
Is there another way to do this?
4 Replies
ZachDaniel
ZachDaniel•3y ago
Currently, the only way would be to switch to a manual action and implement the logic with ecto. Atomic updates will be coming along with bulk actions and at that point you’ll be able to update with an expression. If you need a guaranteed atomic update and you are using ash_postgrse, you can take a lock on the record in a before_action hook and read the value again before updating.
\ įžµįžµįžµ
\ įžµįžµįžµOP•3y ago
Ok, awesome! I can forego atomicity for now, but glad to hear that's on the way šŸ™‚ I thought that maybe it might be interesting to make set_attribute additionally accept a 1-arity function which would be passed the existing value and produce a new value to set.
change set_attribute :count, &(&1 + 1)
change set_attribute :count, &(&1 + 1)
Not atomic, but useful and more general.
ZachDaniel
ZachDaniel•3y ago
Yeah, I could see the use there šŸ™‚ Could work similar to the before_action changes and the like, to support anonymous functions
\ įžµįžµįžµ
\ įžµįžµįžµOP•3y ago
Cool, I'll throw together a PR and we can discuss. Mate, could I maybe get you to take a look at https://discord.com/channels/711271361523351632/1087881932282548284 ?

Did you find this page helpful?