But Poison Encoder wants a key as string or atom for the coordinates map. I do understand postgres does not like tuple as key for jsonb.
So, is there an easy way to transform the tuple key to string before saving to database, then back to tuple after loading? Should I look into changeset or poison encoder? If possible, I would like to keep the more expressive key tuple form for data struct and the string key for db.
Another possibility that @michalmuskala and @mitchellhenke explained to me when I was asking on the #ecto Slack channel yesterday how you could store arbitrary data in a column, would be to create the following type:
defmodule Anything do
@behaviour Ecto.Type
def type, do: :binary
# Provide our own casting rules.
def cast(term) do
{:ok, term}
end
# When loading data from the database, we are guaranteed to
# receive an integer (as databases are strict) and we will
# just return it to be stored in the schema struct.
def load(binary), do: {:ok, :erlang.binary_to_term(binary)}
# When dumping data to the database, we *expect* an integer
# but any value could be inserted into the struct, so we need
# guard against them.
def dump(term), do: {:ok, :erlang.term_to_binary(term)}
end
This will store any Elixir data type, regardless of what it is, in a binary column. The only disadvantage this has over using Postrex + jsonb + some logic to convert your things to JSON, is that a jsonb-type-column can be searched to some extent, while an encoded binary can not. However, for just storing some information, this should be enough.