Can I instruct Ash to force update a CiString value regardless of comparison result?
I'm using
Ash.CiString
on a resource field (backed by postgres citext
) for all the uniqueness constraint validation goodness, but recently discovered that Ash is skipping updates to the field value when only the case has changed.
I know, I know: why am I using a CiString
if I don't want case-insensitive comparison? Because I don't want to clobber other records with the same case-insensitive name. But I do want to give the user control to update the casing of the value on an individual record. I have a NameCollissionPrevention
validation that ignores the current record in question when deciding if the record update is valid, so I don't think this is programmer error, it feels like Ash is ignoring the field in the update b/c it compares as equal.
Maybe CiString isn't the right tool for the job in this scenario. I'm curious if Ash provides a way to say "you can update this value to anything (and any case) you want".
Thanks in advance for any ideas you can provide.Solution:Jump to solution
I ended up modifying it a bit b/c the
:name
arg isn't required:
```
change(fn changeset, _ctx ->
case changeset.arguments[:name] do...4 Replies
From what I can tell, the field
:name
is pulled from the attributes if the case-insensitive comparison returns a match. Is there a way to force that in? Maybe put a pre-action hook in place and put the name
in a private context var, and then set it on the changeset?
I tried adding a before_action but it appears to be running after (or inside?) my change action, even though the code is registered before it.
Ok, if I add the :name
field as an argument instead of just listing it as a field in accept
it now comes through on the changeset and I can use force_change_attribute/3
, but that's still not passing the value through to postgres to updateYeah...I legitimately hadn't considered this as a thing 😅
What you want to do makes perfect sense
Try
change atomic_update(:field, expr(^arg(:name)), cast_atomic?: false)
We should add an option to change attribute not to compare with the old one but it's a bit complex. This is a hack to workaround it temporarily
If that works LMK and we can open an issue about it 🙂I'll be damned, that worked. Not in a million years would I have thought about doing that. Thanks for saving my bacon yet again.
Solution
I ended up modifying it a bit b/c the
:name
arg isn't required: