Is there any way to have an assoc on a schema that is related to a has_many, but only returns the most recent entry

For example if a User was checking in at Locations, that were being stored each time, we’d have something like this:

schema "users" do
  has_many(:locations, MyApp.Schemas.Location)
end

What I would like to also add is something like:

has_one(:last_location, MyApp.Schemas.Location, ...some order by inserted_at/limit function...)

Is this possible? What’s the best way to do this?

Associations don’t support limit directly, unfortunately.

You could use Ecto.Query.preload with an appropriate query, but it will add complexity.

As an alternative, consider the way your application writes data. Is a Location ever changed to a different User, by updating user_id? If it isn’t, then it would be safe to denormalize a little:

schema "users" do
  has_many(:locations, MyApp.Schemas.Location)
  belongs_to(:last_location, MyApp.Schemas.Location)
end

and then ensure that any time you add a new Location record you also update the corresponding User.

This approach is most valuable if the application mostly reads from last_location, as it keeps the common queries as simple as possible.

The User ID doesn’t change, the table is just User_Ids and Postgis.Geom:

schema "locations" do
    field(:geom, Geo.PostGIS.Geometry)
    field(:user_id, :binary_id)

    timestamps()
  end

I’m a bit unclear on how that line you have:

belongs_to(:last_location, MyApp.Schemas.Location)

would work. For a given user they could have 0,1,…N Locations, so I’m unclear how just creating a belongs_to entry would always pull the last one. Is there some other field I need to add?

Edit:
Oh, I see, I would be storing a last_location_id on the user’s table?

Yup - the code that creates a new Location would also ensure that the last_location_id field on the user was updated.