Is there anyway to return a changeset from validation module?

I have a not-simple validation using pure Ecto in Phoenix project. And I want to port over to the project that is using Ash. With Ecto. we used to add errors to changeset in each function def validate_something(changeset, some) do changeset |> validate_something_1(some) |> validate_something_2(some) |> validate_something_3(some) end In each function, if the validation passes, we simply pass the changeset through. Otherwise, we add an error to the changeset. This way, the end user can see all errors at once when the changeset is returned. But in custom validations in Ash, I found that we need to return either :ok or {:error, field: field, message: message}, and we can't return the changeset itself. Is there any way to support this pattern? Or are we expected to stop validation after the first failure?
6 Replies
ZachDaniel
ZachDaniel•4mo ago
Neither 😄 You can't return a changeset from validations, but one validation returning {:error, error} doesn't stop the other validations from running.
Taehwan
TaehwanOP•4mo ago
So it is not a good practice to pipe multiple validate functions? because It is kinda tricky def validate_something_1(changese, some) do if true do # validation is good changeset # we should pass changeset for next function else # validation failed # we can't return {:error, field: field, message: "error message"} because we need a changeset for next function # So let me add an error to changeset Ash.Changeset.add_error(changeset, "some error") end end def validate_something_2(changeset, some) do if true do # validation is good changeset # we should pass changeset for next function else # validation failed # we can't return {:error, field: field, message: "error message"} because we need a changeset for next function # So let me add an error to changeset Ash.Changeset.add_error(changeset, "some error") end end And for last function def validate_something_3(changeset, some) do if true do :ok # if we pass :ok, this marks the changeset valid and previous errors are ignored else # we can't pass just changeset from validation.. so added errors are ignored. {:error, field: field, message: "error message"} end end
ZachDaniel
ZachDaniel•4mo ago
Well typically you'd have multiple validations
validate Foo
validate Bar
validate Baz
validate Foo
validate Bar
validate Baz
But you can also return multiple errors {:error, [[message: ""], [message: ""]]}
Taehwan
TaehwanOP•4mo ago
Oh, do you mean splitting them into multiple validation modules?
ZachDaniel
ZachDaniel•4mo ago
Yes
Taehwan
TaehwanOP•4mo ago
Okay. Thanks

Did you find this page helpful?