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
Neither 😄
You can't return a changeset from validations, but one validation returning
{:error, error}
doesn't stop the other validations from running.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
Well typically you'd have multiple validations
But you can also return multiple errors
{:error, [[message: ""], [message: ""]]}
Oh, do you mean splitting them into multiple validation modules?
Yes
Okay. Thanks