Prevent action's changes from being run on `AshPhoenix.Form.validate`

Hello, I have an resource A that has a filed let's say capacity , belongs_to relationship to B resource and create action that has a change LoadDefaultFromRelationship . This change basically fetches the capacity from B resource if none was given in the create action params for A. The problem with such approach is that every time we invoke the AshPhoenix.Form.validate it makes a query to the database for this default value. Is there any way to prevent this change being run on AshPhoenix.Form.validate but still apply on create action?
3 Replies
ZachDaniel
ZachDaniel3y ago
You want lifecycle hooks for this in your change, do the logic in a before_action hook, i.e
def change(changeset, _, _) do
Ash.Changeset.before_action(changeset, fn changeset ->
# do expensive work here
end)
end
def change(changeset, _, _) do
Ash.Changeset.before_action(changeset, fn changeset ->
# do expensive work here
end)
end
That hook will only be called just prior to the form being submitted in the case of forms Essentially any "expensive" work should be pushed to a lifecycle hook, and definitely anything with side effects. The rule of thumb is "If this action was going to be put into a phoenix form, would I want this to happen on every keystroke, or only when the form is submitted?". If the former, then it can go in the change function directly. If the latter, it should be in a lifecycle hook.
Myrmyr
MyrmyrOP3y ago
Thanks for the answer! Unfortunately this has caused another problem, because the default duration is taken from B only in before_action callback, the changeset itself is invalid, because the duration is not set, and does not run the before_action callback at all. Would it be possible, to run the validation after the before_action, but only when the action is being commited, but run validation normally for AshPhoenix.Form?
ZachDaniel
ZachDaniel3y ago
You should set allow_nil_input :duration on the action, which says “normally this is required, but I’ll do something in the action to set it”

Did you find this page helpful?