Ecto will likely raise an error if you try to cast a plain string as UUID so I suggest to determine the datatype on the application level:
live "/records/:opaque_id", RecordsLive.Show
def get_record(opaque_id) do
Record
|> where(^opaque_id_to_query(opaque_id))
|> Repo.one()
end
defp opaque_id_to_query(opaque_id) do
cond do
match?({_, ""}, Integer.parse(opaque_id)) -> [id: opaque_id]
match?({:ok, _}, Ecto.UUID.cast(opaque_id)) -> [uuid: opaque_id]
true -> [slug: opaque_id]
end
end






















