I have a resource Ride and a resource Person. They are many-to-many related through PersonRide, which has an extra field ‘seat’.
It’s possible to add a person to a ride with a seat by creating a PersonRide directly or by using manage_relationships with join_keys: [:seat]
I’d like to automatically load the seat when loading a ride with load: [:people]
I’m trying to add a calculation to the Person resource:
calculate :seat, :atom, Calculations.Seat do
argument :ride_id, :uuid
public? true
end
With a calculation like this:
defmodule Calculations.Seat do
def load(_query, _opts, _context) do
[person_rides: [:seat, :ride_id]]
end
def calculate(records, _opts, %{arguments: %{ride_id: ride_id}}) do
Enum.map(records, fn record ->
Enum.find_value(record.person_rides, &(&1.ride_id == ride_id && &1.seat))
end)
end
end
i can do
assert Ash.load!(person, seat: [ride_id: ride_id]).seat == :shotgun
(unsure though if i can use this to later auto-load the seats when reading a ride)
But this gets all the PersonRides for the Person and then filters them in Elixir.
Is there a way to do this more efficiently? Like altering the query in load/3 or somehow adding a filter to the load statement returned from load/3?