I have a resource called Entity which has a one to many relationship with a resource called SkipTrace.
I have an action in the SkipTrace that will return all skip traces for a specific entity id.
In my LV page, I have a list of entities and I want to load their skip traces using the LV’s update_many function. In other words, I want to call my action from the SkipTrace once but instead of sending the entity id as argument, I want to send a list of entities ids, return all of them and group them by the entity id.
Can I do that by reusing my already existing read action from the SkipTrace resource? What is the most “idiomatic” way to do that in Ash?
If you have an action that takes an id as an argument and applies a filter, then there isn’t a way to use it as you’ve described, as it will always apply the filter for a single item.
If you have the actual Entity records then you can do it very simply, just Ash.load(entities, :skip_traces). If you only have the ids you can do something similar ids |> Enum.map(&%Entity{id: &1}) |> Ash.load(:skip_traces).
You could also make a separate action that accepts an ids argument instead of just id, and does a filter expr(id in ^ids)
read :action_name do
argument :id, :uuid
argument :ids, {:array, :uuid}
filter expr(
cond do
not is_nil(^arg(:ids)) -> id in ^arg(:ids)
not is_nil(^arg(:id)) -> id == ^arg(:id)
true -> true
end
)
end
I wrote all of the above and then got majorly distracted, since then @mindok has pointed out a true thing which is that the simplest way is always going to be loading on records that you already have
Thanks! I don’t have the entity available in the component, only its id, so doing the ids |> Enum.map(&%Entity{id: &1}) |> Ash.load(:skip_traces) trick is what I needed!