spacebat

spacebat

Best fix for "Changeset has already been validated for action" warning

I recently updated from an early Ash 3.x to the most recent, and find at runtime a lot of warnings like:

Changeset has already been validated for action :create.

For safety, we prevent any changes after that point because they will bypass validations or other action logic.. To proceed anyway, you can use `force_change_attribute/3`. However, you should prefer a pattern like the below, which makes any custom changes *before* calling the action.

  Resource
  |> Ash.Changeset.new()
  |> Ash.Changeset.change_attribute(...)
  |> Ash.Changeset.for_create(...)

So far in my application I have a lot of actions that use Ash.Changeset.change_attribute/3 within change before_action(fn ....) blocks. This is usually to support computed defaults that depend on other attributes/arguments so that the call sites for the actions are nice and clean.

The simplest thing is to change all these occurrences to Ash.Changeset.force_change_attribute/3 but the warning advises against it.

I could write wrapper functions for all these actions that compute the defaults before calling the action, as advised by the warning, but then the actions themselves become far less convenient to call directly, and the functions will be located elsewhere in the module, not right next to the action they are related to.

Maybe wrapper actions would be better, so have a create :raw_create that defaults nothing, and create :create would accept no attributes, only arguments, compute the defaults and call the raw_create action, but that feels verbose and undesirable.

Validations could be removed from the attributes and applied explicitly within each action, but that would lose a lot of the attribute metadata and be more repetitive and error prone.

I don’t see a change before_validation hook but if it existed that would be a simple fix.

It feels like I’ve been using Ash wrong but it’s unclear what the best approach is, perhaps I’m missing something obvious that I didn’t notice in the docs.

Most Liked

spacebat

spacebat

That’s a lot to chew on, thanks I’m sure re-reading this in the morning will be fruitful. I can’t wait for the Ash book :slight_smile:

Where Next?

Popular in Questions Top

9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
dotdotdotPaul
Okay, I’m having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I’m sure I’...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New

Other popular topics Top

New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New

We're in Beta

About us Mission Statement