Hi,
I have an action called ‘start’:
update :start do
change transition_state(:active)
require_atomic? false
validate attribute_equals(:enough_parties_defined?, true)
validate attribute_equals(:has_parties_with_no_members?, false)
validate Validations.HasDocuments,
before_action?: true
change Changes.SendInvitesToAllParticipants
end
It has some validations that are based on calculations :enough_parties_defined?
and :has_parties_with_no_members?
.
Currently I do:
project = Ash.load!(project, [:has_parties_with_no_members?, :enough_parties_defined?])
Project.start(project)
I would like to avoid the load!
step, as it is leaking implementation details to the call-site.
Can I make my action ensure these are loaded and lazy load them if needed?
You can add a change before your validations that loads the data.
I think something like this should work
update :start do
require_atomic? false
change fn %{data: data} = changeset, _ ->
data = Ash.load!(
data,
[:has_parties_with_no_members?, :enough_parties_defined?],
# you probably want to add this because the change can be run
# multiple time, but you need to make sure you don't pass a resource
# with stale values, otherwise it might be better to do all the validations
# and the loading as before_actions
lazy?: true
)
%{changeset | data: data}
end
change transition_state(:active)
validate attribute_equals(:enough_parties_defined?, true)
validate attribute_equals(:has_parties_with_no_members?, false)
validate Validations.HasDocuments,
before_action?: true
change Changes.SendInvitesToAllParticipants
end
changes and validations are run in the order they are specified in the dsl
1 Like